类中的静态信息

时间:2013-08-16 11:01:25

标签: c# generics inheritance

我希望我的几个课程能够告诉我其中有多少个字段,并且我想通过继承来强制执行我的所有课程,如下所示:

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

有没有办法做到这一点,或者在这里反思是唯一的出路?

谢谢!

3 个答案:

答案 0 :(得分:0)

看起来似乎没有真正需要在这里专门使用字段,如果你转而使用属性,你可以覆盖每个派生的属性实现,即

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

您可以使用单独的静态类来存储字段计数或任何特定于类型的数据。静态类中的静态字段是每个类型唯一的,这意味着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;
        }
    }
}