【问题标题】:Getting an Enum or Static Property from Generic Reference Type <T>从通用引用类型 <T> 获取枚举或静态属性
【发布时间】:2012-02-10 15:58:33
【问题描述】:

因此,如果class 中有一个名为Barenum 属性,为什么在这种情况下我不能访问enum 属性或type &lt;T&gt; 的任何static 属性。我含蓄地声明 &lt;T&gt; 属于 type Bar。只是想知道这仅仅是泛型的限制还是 enum type 本身的限制。

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

更新

@Frederik Gheysels 的 回答中提到,如果我有一个简单地从 Bar 派生的 class,那么我将无法访问 enum 或任何 @987654339 @ 的base。这是不正确的,这可以编译并有效。

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

【问题讨论】:

  • 您为什么希望能够做到这一点?这里的用例是什么?
  • 您是否正在尝试完成类似于this 的事情?
  • @Jon Skeet,用例,没有。有人问我为什么这是不可能的。我唯一能想到的是,它只是泛型的一个限制。我只是想看看有没有更好的答案。
  • @Gabe:值得牢记的是“为什么 X 不可能?”的正确答案。通常是“因为它没有足够的用处来设计、指定、实施和测试资源”——其中包括“它作为一个想法从根本上被打破了”:)

标签: c# generics .net-4.0


【解决方案1】:

您的Cars 枚举是Bar 类中的嵌套类型。它不是Bar 的成员属性/方法。 因此,这是不可能的。

Cars 只是 Bar 的嵌套类型。当您创建另一个派生自 Bar 的类时,我们将其命名为 Bar2,您也无法访问 Bar2.Cars,因为不会创建该类型。嵌套类型不是实例成员,因此不会被继承。

【讨论】:

  • 这并不能完全回答为什么这是不可能的问题。
  • Bar 的成员 - 类型是成员的一种。
  • 是的,但特定于 Bar。将允许作为 T 的通用参数的 Bar 的继承类型将没有 .Cars 类型。
  • 如果我有一个简单地从Bar 派生的class Bar2,我可以访问enumstatic 属性。检查我更新的问题。
【解决方案2】:

一个潜在的解决方法是允许Foo&lt;T&gt;Bar 继承以公开静态成员。要访问静态成员Name,您需要提供一个虚拟访问器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; }
    }
}

【讨论】:

  • Foo 可能不是Bar。如果您考虑任何集合类型泛型,它很可能不是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2014-06-10
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多