0

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

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

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

谢谢!

4

3 回答 3

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
于 2013-08-16T11:15:52.347 回答
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;
        }
    }
}
于 2013-08-23T15:38:15.330 回答
0

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

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

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

于 2013-08-16T11:55:39.437 回答