generate - ¿Por qué C#no permite propiedades genéricas?
params comments c# (5)
Creo que no usar un getter / setter automático ilustra por qué esto no es posible sin tener una "T" definida a nivel de clase.
Intenta codificarlo, lo natural sería hacer esto:
IEnumerable<T> _all;
IEnumerable<T> All
{
get { return _all; }
}
Debido a que su campo usa "T", entonces "T" debe estar en la clase en la que CLR sabe qué es "T".
Cuando está utilizando un método, puede retrasar la definición de "T" hasta que realmente llame al método. Pero con el campo / propiedad, "T" debe declararse en un solo lugar, a nivel de clase.
Una vez que declara T en la clase, crear una propiedad se vuelve bastante fácil.
public class TestClass<T>
{
IEnumerable<T> All { get; }
}
uso:
var myTestClass = new TestClass<string>();
var stuff = myTestClass.All;
Y al igual que el parámetro de tipo "T" en un método, puede esperar hasta que realmente cree una instancia de TestClass para definir qué "T" será.
Me preguntaba por qué no puedo tener una propiedad genérica en una clase no genérica de la manera en que puedo tener métodos genéricos. Es decir:
public interface TestClass
{
IEnumerable<T> GetAllBy<T>(); //this works
IEnumerable<T> All<T> { get; } //this does not work
}
Leí la answer @Jon Skeet, pero es solo una declaración, que probablemente esté en algún lugar de las especificaciones.
Mi pregunta es ¿por qué en realidad es así? ¿Se evitó algún tipo de problema con esta limitación?
Esta publicación del blog de propiedades genéricas de Julian Bucknall es una buena explicación. Esencialmente es un problema de asignación de montón.
Hice algo así. Se escribe cheques en tiempo de ejecución.
public class DataPackage
{
private dynamic _list;
public List<T> GetList<T>()
{
return (List<T>)_list;
}
public void SetList<T>(List<T> list)
{
_list = list;
}
public string Name { get; set; }
}
Mi conjetura es que tiene algunos casos de esquina desagradables que hacen que la gramática sea ambigua. De la mano, esto parece que podría ser complicado:
foo.Bar<Baz>=3;
Si eso se analiza como
foo.Bar<Baz> = 3;
O:
foo.Bar < Baz >= 3;
Técnicamente, el CLR solo admite tipos y métodos genéricos, no propiedades, por lo que la pregunta es por qué no se agregó al CLR. Probablemente, la respuesta a eso sea simplemente "no se consideró que trajera suficiente beneficio para que valga la pena los costos".
Pero más fundamentalmente, se consideró que no traía ningún beneficio porque no tiene sentido semánticamente tener una propiedad parametrizada por un tipo. Una clase de Car
podría tener una propiedad de Weight
, pero no tiene sentido tener una propiedad de Weight<Fruit>
y una propiedad de Weight<Giraffe>
.