C# 如何从类型参数中提取静态值

C# 如何从类型参数中提取静态值,c#,generics,types,C#,Generics,Types,代码如下所示 public class One<T> where T : Two { public static int Y; static One() { // Y is to be initialised with the Z value from T // this code does not compile // Y = T.Z; } public int X { get { return Y; }

代码如下所示

  public class One<T> where T : Two {
    public static int Y;  
    static One() {
      // Y is to be initialised with the Z value from T
      // this code does not compile
      // Y = T.Z;
    }
    public int X {  get { return Y; } }
  }

  public class Two {
    public static int Z = 42;
  }

  public class Three {
    public void Main() {
      One<Two> a = new One<Two>();
      Console.WriteLine("X = {0}", a.X); // should say 42
    }
  }
公共一类,其中T:2{
公共静态智力;
静态一(){
//Y将用T中的Z值初始化
//此代码不编译
//Y=T.Z;
}
公共int X{get{return Y;}}
}
公共二班{
公共静态int Z=42;
}
公共三班{
公共图书馆{
一个a=新的();
WriteLine(“X={0},a.X);//应该是42
}
}
其思想非常简单:从作为类型参数传递的另一个类中的另一个静态值初始化一个类中的静态值。这并没有什么“不安全”的地方,但是自然的方式是不会编译的(参见代码)


我搜了这么多,发现了几处险情,但都没有找到。我试过一些方法,包括反思,但都没有用。非常感谢任何解决方案甚至提示。

看起来它应该能工作。然后你开始键入
T.Z
,意识到你的直觉与编译器是一致的
T
是一个类型参数,它不是一个成熟的type-y类型

无论如何,这是有效的:

static One()
{
    // Y is to be initialised with the Z value from T
    var typeT = typeof(T);
    var zFieldInfo = typeT.GetField("Z");
    Y = (int) zFieldInfo.GetValue(null);
}

是的,它使用反射,但它只能运行一次。

Flydog给了你一些你可以使用的东西;我只是想快速记下我/吉米/谜一样的评论:

感觉就像你希望在某个点上把第二类子类化,然后改变Z;您可以推断,如果新的类3(静态Z为43,由两个派生而来)与一个类结合使用,那么您将得到一个
.X
,即43。问题在于静态的东西是不能被覆盖的;它们是在编译时解决的,在某些情况下,它们看起来像是在进行重写,但实际上它是重载或隐藏的,编译器按照定义的顺序从继承树中选择具有特定名称的内容

因为静态的东西不会继承(也可以说不需要继承,因为它们在编译时总是为您(开发人员)所知),所以不期望有一天会有人对您的代码进行子类化并编写:

One<Four> a = new One<Four>();
One a=新的一个();

你的代码需要选择他们设置的Z并使用它。您知道自己的Z,并且可以在编译时适当地使用它们,并且他们知道自己的Z,并且应该适当地使用它们。但我知道你要带着T.Z去哪里

为什么它需要是静态变量而不是实例变量?如果在
Y=Two.Z,它可能会打印出来,但它是一个meh…你得到了什么?你知道在一个一中找到的所有东西都是二,因此都有一个Z,那么为什么不直接说
Console.WriteLine(“X={0}”,Two.Z);//应该说42
?我认为这个例子太做作了,以至于完全不知道为什么它是个好主意;你能举一个不那么做作的例子吗?@CaiusJard-你的评论很贴切。如果我们能写出
公共虚拟静态intz=42那么允许这个OP的构造可能是有意义的,但我们不能这样做。@CaiusJard:真正的例子是试图解决一个有很多无关细节的复杂问题。但核心是:
One
将是两个
s的集合,其中两个级别共享一个共同的唯一标识符,
Two
无法知道
One
,集合可能为空。因此,
One
必须从
Two
中的静态文件中获取其id。是的,你是对的。感觉应该有更好的方法,但我认为这就是一切。谢谢。没有子类化,不是吗。问题是在集合和成员类之间共享唯一标识符,此时集合只能从成员的类获取其id。无法使静态超负荷显然是其他可能解决方案的障碍。