为什么C#不允许通用属性?
我想知道为什么我不能像通用方法那样在非generics类中拥有generics属性。 即:
public interface TestClass { IEnumerable GetAllBy(); //this works IEnumerable All { get; } //this does not work }
我读了@Jon Skeet的答案 ,但这只是一个声明,很可能是规范中的某个地方。
我的问题是为什么它实际上是这样的? 这种限制是否避免了一些问题?
从技术上讲,CLR只支持generics类型和方法,而不支持属性,因此问题是它没有添加到CLR中。 对此的答案可能只是“它不被视为带来足够的好处,值得花费”。
但更根本的是,它被认为没有带来任何好处,因为在一个类型的参数化属性中,在语义上没有意义。 Car
类可能具有Weight
属性,但是具有Weight
和Weight
属性是没有意义的。
这篇来自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; } }