5

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
    }
}
Gabe
  • 49,577
  • 28
  • 142
  • 181
  • 4
    Why would you *want* to be able to do that? What's the use case here? – Jon Skeet Feb 10 '12 at 16:03
  • Similar to http://stackoverflow.com/questions/196661/calling-a-static-method-on-a-generic-type-parameter – AlG Feb 10 '12 at 16:03
  • Are you trying to accomplish something similar to [this](http://stackoverflow.com/questions/4704201/what-is-the-best-way-to-override-enums)? – M.Babcock Feb 10 '12 at 16:05
  • @Jon Skeet, the use case, well there is none. Someone asked me why this is not possible. The only thing I could come up with, is that it's simply a limitation of generics. I just wanted to see if there was a better answer. – Gabe Feb 10 '12 at 22:02
  • 2
    @Gabe: it's worth bearing in mind that the right answer to "why is X not possible?" is often "because it's not useful enough to merit the resources to design, specify, implement and test" - which includes "it's fundamentally broken as an idea" :) – Jon Skeet Feb 10 '12 at 22:08

2 Answers2

1

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.

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
1

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; }
    }
}
SliverNinja - MSFT
  • 31,051
  • 11
  • 110
  • 173