【问题标题】:static information in a class类中的静态信息
【发布时间】:2013-08-23 23:38:15
【问题描述】:

我希望我的几个类能够告诉我其中有多少字段,并且我想通过继承强制我的所有类都具有此功能,如下所示:

// this code does not compile
abstract class Base
{
    abstract static const int FieldCount = -1
}

class Node : Base
{
    int x, y, z; // has three fields, so:
    override static const int FieldCount = 3;
}

class Way : Base
{
    int w, x, y, z; // has four fields, so:
    override static const int FieldCount = 4;
}

我无法让它工作,不是使用接口或抽象基类。我需要这些信息仅适用于类型,而不是通过类的实际实例(因此是静态的)。

class EnumerableDataReader<TSource> : IDataReader where TSource : Base {
    public int FieldCount {
        get {
            return TSource.FieldCount <- access the static info, does not work
        }
    }
}

有没有办法做到这一点,或者反射是唯一的方法吗?

谢谢!

【问题讨论】:

  • 当然,反思是最好的选择——否则即使有办法使语法正常工作,还有什么能阻止您报告错误的数字?
  • 您不能对静态成员使用多态性。您只能将override 用于方法、事件和属性。不是FieldsConstants
  • @James 即使 Op 也更改为 Property 这也不起作用。因为成员是静态的
  • @SriramSakthivel 是的,注意到除了编译问题之外还有更多问题!
  • static 和“继承”不能一起使用。事实上,static 和 OO 不能一起工作。 (不在 C++/Java/C# 模型中。)

标签: c# generics inheritance


【解决方案1】:

看起来没有任何真正需要在这里专门使用字段,如果您改为使用属性,则可以覆盖每个派生的属性实现,即

abstract class Base
{
    public static int FieldCount { get { return -1; } }
}

class Node : Base
{
    int x, y, z; // has three fields, so:
    public new static int FieldCount { get { return 3; } }
}

class Way : Base
{
    int w, x, y, z; // has four fields, so:
    public new static int FieldCount { get { return 4; } }
}
...
Console.WriteLine(Base.FieldCount) // -1
Console.WriteLine(Node.FieldCount) // 3
Console.WriteLine(Way.FieldCount) // 4

要解决问题的另一半,您需要依赖反射,即

class EnumerableDataReader<TSource> where TSource : Base
{
    public int FieldCount
    {
        get {
            return (int)typeof(TSource).GetProperties().Single(x => x.Name == "FieldCount").GetValue(null);
        }
    }
}
...
var reader = new EnumerableDataReader<Node>();
Console.WriteLine(reader.FieldCount); // 3

【讨论】:

    【解决方案2】:

    静态成员不支持虚拟继承,因为虚拟继承是关于解析给定实例的成员。实例上不存在静态成员。

    您可以使用反射来读取给定类型参数或Type 实例的静态成员。

    您的设计中有很多“魔法”。新开发人员可能不会立即接受具有特殊命名字段的约定。我会考虑将设计更改为 TSource 类型上的 自定义属性

    【讨论】:

      【解决方案3】:

      您可以使用单独的静态类来存储字段计数或任何特定于类型的数据。静态类中的静态字段对于每种类型都是唯一的,这意味着 MyStaticClass.FieldCount 是与 MyStaticClass.FieldCount 分开的变量。

      此外,您可以使用静态构造函数来设置类第一个类型被触及的值。

      例如,

      public static class FieldCountStatic<T>
      {
          public static int FieldCount { get; set; }
      }
      
      class Node
      {
          static Node()
          {
              FieldCountStatic<Node>.FieldCount = 3;
          }
      
          int x, y, z;
      }
      
      class Way
      {
          static Way()
          {
              FieldCountStatic<Way>.FieldCount = 4;
          }
      
          int w, x, y, z; // has four fields
      
      }
      
      class EnumerableDataReader<TSource> : IDataReader
      {
          public int FieldCount
          {
              get
              {
                  return FieldCountStatic<TSource>.FieldCount;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-28
        • 2015-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多