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

Sun*_*nov 27 c# language-design language-specifications

我想知道为什么我不能在非泛型类中拥有泛型属性,就像我可以使用泛型方法一样.即:

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

   IEnumerable<T> All<T> { get; } //this does not work
}
Run Code Online (Sandbox Code Playgroud)

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

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

Tim*_*mwi 14

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

但更重要的是,它被认为没有带来任何好处,因为在一个类型的参数化属性上,在语义上没有意义.一个Car类可能有一个Weight属性,但拥有一个属性是没有意义Weight<Fruit>Weight<Giraffe>.

  • 我认为如果您查看其他一些答案,他们不允许这样做是有原因的,这不仅仅是“时间太多”的问题。 (2认同)
  • 我不明白“毫无意义的语义论证”。与类上的泛型方法的情况一样,目的通常是使类的子类型成为泛型,而不是将整个类变成它不是的东西(如将汽车变成水果的示例)。更有可能的是,对通用类的内部组件进行一些操作(在属性的情况下获取或设置),例如内部与外部电子设备或燃油、制动、转速表,其中操作同样适用于每个仪表。听起来更有可能是在太硬的篮子里。 (2认同)

Jam*_*See 11

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

  • 与其他答案一样,这篇博文完全没有涉及通用属性的问题,只涉及通用字段.这并不能解释为什么我们不能拥有通用属性. (4认同)
  • 这正是我所说的.问题是*field*.博客条目中没有任何内容说明为什么我们不能在没有字段*的情况下拥有*泛型属性.属性只是一个get方法(以及可选的set方法),它可以完全是通用的.它只是*字段*不能. (4认同)
  • 这篇文章非常可怕.假设所有属性都有一些后备存储,而这种情况并非如此. (4认同)
  • 想象一下异构的集合类.拥有一个获取给定类型集合中所有对象的操作可能会很好.如果你有泛型属性,那可能是`collection.OfType <Blah>`.相反,它必须是方法`collection.OfType <Blah>()`,即使它不带参数. (3认同)