类中的静态信息

本文关键字:信息 静态 | 更新日期: 2023-09-27 18:27:53

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

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

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

谢谢!

类中的静态信息

这里似乎没有任何真正需要使用字段的地方,如果您改用属性,您可以覆盖每个派生的属性实现,即

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

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

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

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

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

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

例如,

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