2015-06-05 5 views
21

Verwenden von automatischen Eigenschaften für explizite Schnittstellenimplementierung was not possible in C# 5, aber jetzt, dass C# 6 getter-only auto-properties unterstützt, sollte dies jetzt möglich sein, oder?Explizite Implementierung einer Schnittstelle mit einer Getter-only-Eigenschaft (C# 6-Feature)

Das Erstellen der Auto-Eigenschaft ist in C# 6 erfolgreich, aber wenn Sie versuchen, ihm im Konstruktor einen Wert zuzuweisen, müssen Sie zuerst this in den Schnittstellentyp umwandeln, da die Implementierung explizit ist. Aber das ist, wo beide VS 2015 RC und VS-Code 0.3.0 Anzeige der Fehler, der in dem Kommentar zu sehen ist:

using static System.Console; 

namespace ConsoleApp 
{ 
    public interface IFoo { string TestFoo { get; } } 

    public class Impl : IFoo 
    { 
     // This was not possible before, but now works. 
     string IFoo.TestFoo { get; } 

     public Impl(string value) 
     { 
      // ERROR: Property or indexer 'IFoo.TestFoo' cannot be assigned to -- it is read only. 
      ((IFoo)this).TestFoo = value; 
     } 
    } 

    public class Program 
    { 
     // Yes, not static. DNX supports that (for constructor DI). 
     public void Main(string[] args) 
     { 
      IFoo foo = new Impl("World"); 

      WriteLine($"Hello {foo.TestFoo}"); 
      ReadKey(true); 
     } 
    } 
} 

Hinweis: Ich habe die ursprüngliche Frage aktualisiert, die einen konstanten Wert TestFoo gesetzt. In meinem realen Szenario stammt der Wert von einem Objekt, das in den Konstruktor eingefügt wird. Die answer by Daniel A. White ist ausgezeichnet, wenn der von der Eigenschaft zurückgegebene Wert bei der Initialisierung festgelegt werden kann.

Dort heißt es:

oder der Indexer 'IFoo.TestFoo' kann nicht zugewiesen werden - es ist nur gelesen wird.

Gibt es einen Weg, oder muss ich noch Eigenschaften mit Hintergrundfeldern für diesen Fall verwenden?

Ich verwende Visual Studio 2015 RC und Visual Studio Code 0.3.0 mit DNX451 1.0.0-beta4.

Ich habe raised an issue over at the Roslyn GitHub page.


Die possible duplicate ist eine Frage, über die Definition einer Schnittstelle mit einer regelmäßigen Eigenschaft, die gelesen werden kann. In meiner Frage geht es darum, eine solche Schnittstelle explizit mit einem neuen C# 6-Feature zu implementieren, das dies theoretisch ermöglichen sollte. Siehe die andere Frage, die ich im ersten Satz für eine ähnliche Frage verlinkt habe (aber für C# 5, wo die Getter-Only-Auto-Eigenschaften noch nicht verfügbar waren).

+1

ich denke, es ist nur ein Bug oder der Compiler kann nicht herausfinden, dass es einstellbar ist, weil es hinter der Schnittstelle, die nur Readonly ist. –

+0

@ DanielA.White Es ist nicht viel anders als eine normale Eigenschaft. 'string Foo {bekommen; }} ist jetzt legal, aber in diesem Fall könnten Sie es im Konstruktor setzen. –

+1

@ DanielA.White, ja. Ich denke, der Compiler erlaubt nur direkte Zugriffe auf die Eigenschaft vom Konstruktor und das Casting ist nicht erlaubt. –

Antwort

3

Sie können dieses Problem umgehen, indem Sie eine Nur-Lese-Trägerfeld für Ihre explizit implementiert Eigenschaft. Sie können den injizierten Wert dem Backing-Feld im Konstruktor zuweisen. Die get-Implementierung der expliziten Eigenschaft gibt sie zurück.

public class Impl : IFoo 
{ 
    private readonly string _testFoo; 

    string IFoo.TestFoo => _testFoo; 

    public Impl(string value) 
    { 
     _testFoo = value; 
    } 
} 
1

Ich glaube, Sie wollen, dass diese

string IFoo.TestFoo { get; } = "World"; 
+0

Wahrscheinlich besser raten als meine 'string IFoo.TestFoo {bekommen; privates Set; } 'thought; p – leppie

+0

Tut mir leid, ich hätte klarer sein sollen: Der Wert, der 'TestFoo' gegeben wird, kommt von einem Objekt, das in den Konstruktor injiziert wurde, aber danke. –

+0

@NikontheThird: Funktioniert mein Vorschlag? Ich denke nicht, dass es so sein wird, aber es könnte eine nette "syntaktische Lösung" sein, um die Absicht auszudrücken. Es könnte sich lohnen, ein Thema auf roslyn github zu protokollieren. – leppie

Verwandte Themen