简体   繁体   中英

Getting an Enum or Static Property from Generic Reference Type <T>

So if there is an enum property in a class called Bar , why can't I access the enum property or any static property of type <T> in this situation. I am implicitly declaring that <T> is of type Bar . Just wanted to know if it's simply a limitation of Generics or the enum type itself.

public class Foo<T> where T : Bar
{
     public Foo()
     {
         // This obviously works
         var car = Bar.Cars.Honda;
         var name = Bar.Name;  

         // Why can't I do this ?
         var car2 = T.Cars.Toyota;
         var name2 = T.Name;
     }
}

public class Bar
{
     public static string Name { get; set; }
     public enum Cars
     {
         Honda,
         Toyota
     };
}

UPDATED

In @Frederik Gheysels's answer, it's mentioned that if I have a class that is simply derived from Bar that I wouldn't have access to the enum or any static of the base . That is not correct, this compiles and works.

public class Foo : Bar
{
    public Foo()
    {
        // This all works
        var address = this.Address;
        var car = Foo.Cars.Honda;
        var name = Foo.Name;
    }
}

public class Bar
{
    public static string Name { get; set; }
    public string Address { get; set; }
    public enum Cars
    {
        Honda,
        Toyota
    }
}

your Cars enum, is a nested type inside class Bar . It is not a member property / method of Bar . Therefore, it is not possible.

Cars is just a nested type of Bar. When you create another class, which derives from Bar, lets call it Bar2 , you will not have access to Bar2.Cars neither, since that type will not be created. Nested types are not instance members, and are thus not inherited.

A potential workaround is to allow Foo<T> to inherit from Bar to expose the static members. To access the static member Name , you need to provide a virtual accessor as discussed here .

public class Foo<T> : Bar where T : Bar
{
    public Foo()
    {
        // This obviously works
        var car = Bar.Cars.Honda;
        var name = Bar.Name;

        // use base class for enum accessor ?
        var car2 = Foo<T>.Cars.Toyota;
        var name2 = Foo<T>.Name;

        default(T).Accessor = "test"; // static member access
    }
}

public class Bar
{
    public static string Name { get; set; }
    public enum Cars { Honda, Toyota };
    public virtual string Accessor
    {
        get { return Name; }
        set { Name = value; }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM