wake-up-neo.com

Warum lässt C # keine generischen Eigenschaften zu?

Ich habe mich gefragt, warum ich in nicht generischen Klassen keine generischen Eigenschaften haben kann, wie ich es mit generischen Methoden tun kann. Dh:

public interface TestClass
{
   IEnumerable<T> GetAllBy<T>(); //this works

   IEnumerable<T> All<T> { get; } //this does not work
}

Ich habe die Antwort von @Jon Skeet gelesen, aber es ist nur eine Aussage, die höchstwahrscheinlich irgendwo in den Spezifikationen steht.

Meine Frage ist, warum es eigentlich so ist? Wurden mit dieser Einschränkung Probleme vermieden?

25
Sunny Milenov

Technisch unterstützt die CLR nur generische Typen und Methoden, keine Eigenschaften. Die Frage ist daher, warum sie nicht zur CLR hinzugefügt wurde. Die Antwort darauf ist wahrscheinlich einfach "es wurde nicht angenommen, dass es nicht genug Nutzen bringt, um die Kosten wert zu sein".

Grundsätzlich wurde jedoch davon ausgegangen, dass es keinen Nutzen bringt, da es semantisch nicht sinnvoll ist, eine Eigenschaft durch einen Typ parametrisieren zu lassen. Eine Car-Klasse hat zwar eine Weight-Eigenschaft, aber es macht keinen Sinn, eine Weight<Fruit>- und eine Weight<Giraffe>-Eigenschaft zu haben.

13
Timwi

Dieser Generic Properties Blogeintrag von Julian Bucknall ist eine ziemlich gute Erklärung. Im Wesentlichen handelt es sich um ein Heap-Allocation-Problem.

11
JamieSee

Meine Vermutung ist, dass es einige unangenehme Eckfälle gibt, die die Grammatik mehrdeutig machen. Off-Hand scheint es schwierig zu sein:

foo.Bar<Baz>=3;

Sollte das analysiert werden als:

foo.Bar<Baz> = 3;

Oder:

foo.Bar < Baz >= 3;
2
munificent

Ich denke, wenn Sie keinen automatischen Getter/Setter verwenden, wird deutlich, warum dies nicht möglich ist, ohne dass "T" auf Klassenebene definiert ist.

Versuchen Sie es zu codieren, das Natürlichste wäre dies:

IEnumerable<T> _all;
IEnumerable<T> All
{
    get { return _all; }
}

Da Ihr Feld "T" verwendet, muss "T" in der Klasse sein, und die CLR weiß, was "T" ist.

Wenn Sie eine Methode verwenden, können Sie die Definition von "T" verzögern, bis Sie die Methode tatsächlich aufrufen. Mit dem Feld/der Eigenschaft muss "T" jedoch an einer Stelle auf Klassenebene deklariert werden.

Wenn Sie in der Klasse T deklarieren, wird das Erstellen einer Eigenschaft ziemlich einfach. 

public class TestClass<T>
{
    IEnumerable<T> All { get; }
}

verwendungszweck:

var myTestClass = new TestClass<string>();
var stuff = myTestClass.All;

Und genau wie beim Parameter "T" einer Methode können Sie warten, bis Sie Ihre TestClass instanziiert haben, um zu definieren, was "T" sein soll.

0
viggity