为什么C#不允许通用属性?

我想知道为什么我不能像通用方法那样在非generics类中拥有generics属性。 即:

public interface TestClass { IEnumerable GetAllBy(); //this works IEnumerable All { get; } //this does not work } 

我读了@Jon Skeet的答案 ,但这只是一个声明,很可能是规范中的某个地方。

我的问题是为什么它实际上是这样的? 这种限制是否避免了一些问题?

从技术上讲,CLR只支持generics类型和方法,而不支持属性,因此问题是它没有添加到CLR中。 对此的答案可能只是“它不被视为带来足够的好处,值得花费”。

但更根本的是,它被认为没有带来任何好处,因为在一个类型的参数化属性中,在语义上没有意义。 Car类可能具有Weight属性,但是具有WeightWeight属性是没有意义的。

这篇来自Julian Bucknall的Generic Properties博客文章是一个非常好的解释。 本质上,这是一个堆分配问题。

我的猜测是,它有一些令人讨厌的角落案例,使语法模棱两可。 副手,这似乎有点棘手:

 foo.Bar=3; 

应该解析为:

 foo.Bar = 3; 

要么:

 foo.Bar < Baz >= 3; 

我认为不使用自动getter / setter说明了为什么在没有在类级别定义“T”的情况下这是不可能的。

尝试编码,自然要做的就是:

 IEnumerable _all; IEnumerable All { get { return _all; } } 

因为你的字段使用“T”,所以“T”需要在CLR知道“T”是什么的类上。

当您使用方法时,您可以延迟“T”的定义,直到您实际调用该方法。 但是对于字段/属性,“T”需要在类级别的某个地方声明。

一旦在类上声明了T,创建属性就变得非常简单了。

 public class TestClass { IEnumerable All { get; } } 

用法:

 var myTestClass = new TestClass(); var stuff = myTestClass.All; 

就像方法上的“T”类型参数一样,您可以等到实际实例化TestClass以定义“T”。

我做了那样的事。 它在运行时键入检查。

 public class DataPackage { private dynamic _list; public List GetList() { return (List)_list; } public void SetList(List list) { _list = list; } public string Name { get; set; } }