Why does C# not allow generic properties?

拈花ヽ惹草 提交于 2019-12-17 10:59:11

问题


I was wondering why I can not have generic property in non-generic class the way I can have generic methods. I.e.:

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

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

I read @Jon Skeet's answer, but it's just a statement, which most probably is somewhere in the specifications.

My question is why actually it is that way? Was kind of problems were avoided with this limitation?


回答1:


Technically, the CLR supports only generic types and methods, not properties, so the question is why it wasn’t added to the CLR. The answer to that is probably simply “it wasn’t deemed to bring enough benefit to be worth the costs”.

But more fundamentally, it was deemed to bring no benefit because it doesn’t make sense semantically to have a property parameterised by a type. A Car class might have a Weight property, but it makes no sense to have a Weight<Fruit> and a Weight<Giraffe> property.




回答2:


This Generic Properties blog post from Julian Bucknall is a pretty good explanation. Essentially it's a heap allocation problem.




回答3:


My guess is that it has some nasty corner cases that make the grammar ambiguous. Off-hand, this seems like it might be tricky:

foo.Bar<Baz>=3;

Should that be parsed as:

foo.Bar<Baz> = 3;

Or:

foo.Bar < Baz >= 3;



回答4:


I think not using an automatic getter/setter illustrates why this isn't possible without having "T" defined at the class level.

Try coding it, the natural thing to do would be this:

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

Because your field uses "T", then "T" needs to be on the class the CLR knows what "T" is.

When you're using a method, you can delay definition of "T" until you actually call the method. But with the field/property, "T" needs to be declared in one place, at the class level.

Once you declare T on the class, creating a property becomes pretty easy.

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

usage:

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

And just like the "T" type parameter on a method, you can wait until you actually instantiate your TestClass to define what "T" will be.




回答5:


I made somthing like that. It type checks at run time.

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; }
}


来源:https://stackoverflow.com/questions/8620883/why-does-c-sharp-not-allow-generic-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!