C# 模板方法访问静态变量问题

C# 模板方法访问静态变量问题,c#,.net,C#,.net,假设我有两个类,它们都包含一个静态变量XmlTag。第二个类继承自第一个类。我有一个模板方法,它需要根据所使用的类型获取XmlTag。不必创建该类型的实例,实现这一点的最佳方法是什么?这里有一个例子(不会编译),希望能说明我所说的 class A{ public static readonly string XmlTag = "AClass"; } class B : A { public static readonly string XmlTag = "BClass"; } 此方法当前无效

假设我有两个类,它们都包含一个静态变量XmlTag。第二个类继承自第一个类。我有一个模板方法,它需要根据所使用的类型获取XmlTag。不必创建该类型的实例,实现这一点的最佳方法是什么?这里有一个例子(不会编译),希望能说明我所说的

class A{
public static readonly string XmlTag = "AClass";
}

class B : A {
public static readonly string XmlTag = "BClass";
}
此方法当前无效。。显然无法从类型参数访问静态变量

string GetName<T>(T AClass) where T : A
{
    return T.XmlTag;
}
string GetName(T AClass),其中T:A
{
返回T.XmlTag;
}

如果不借助反射,就无法直接做到这一点

如果你<强>真正的< /强>想要这样做(我鼓励你首先考虑改变你的高级设计):

要获取字段值,请执行以下操作:

var returnValue = typeof(T).GetField("FieldName").GetValue(null);
要获取属性,请执行以下操作:

var returnValue = typeof(T).GetProperty("PropertyName").GetValue(null, null);
要调用方法,请执行以下操作:

typeof(T).InvokeMember("MethodName", BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic, null, null, null);

如果不进行反思,就无法直接做到这一点

如果你<强>真正的< /强>想要这样做(我鼓励你首先考虑改变你的高级设计):

要获取字段值,请执行以下操作:

var returnValue = typeof(T).GetField("FieldName").GetValue(null);
要获取属性,请执行以下操作:

var returnValue = typeof(T).GetProperty("PropertyName").GetValue(null, null);
要调用方法,请执行以下操作:

typeof(T).InvokeMember("MethodName", BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic, null, null, null);

首先,不要把泛型方法当作模板。它们不是模板。它们的行为与模板非常不同;在这种情况下,你期望他们的行为像模板一样,这可能是导致你误入歧途的原因

下面是我写的一系列关于您的场景以及为什么它是非法的文章

请注意,我在第三部分中暗示的“动态”特性实际上是与C#4.0一起提供的


为了解决你的实际问题:“做这件事的最佳方式是什么?”你可能有一些问题,你相信这样的机制可以解决。这种机制在C#中实际上并不存在我们不可能从您希望该机制存在的事实中推断出您实际试图解决的问题。而不是问“我如何才能使这件不可能的事情在C#中工作?”而是描述您遇到的真正问题,我们可以尝试提出一种现有的C#机制来更好地解决您的实际问题。

首先,停止将泛型方法视为模板。它们不是模板。它们的行为与模板非常不同;在这种情况下,你期望他们的行为像模板一样,这可能是导致你误入歧途的原因

下面是我写的一系列关于您的场景以及为什么它是非法的文章

请注意,我在第三部分中暗示的“动态”特性实际上是与C#4.0一起提供的


为了解决你的实际问题:“做这件事的最佳方式是什么?”你可能有一些问题,你相信这样的机制可以解决。这种机制在C#中实际上并不存在我们不可能从您希望该机制存在的事实中推断出您实际试图解决的问题。而不是问“我如何才能使这件不可能的事情在C#中工作?”而是描述您遇到的真正问题,我们可以尝试提出一种现有的C#机制来更好地解决您的实际问题。

为什么不给bas类一个虚拟GetTaName类,并让继承类覆盖该类

class A{
public virtual string GetXmlTagName()
  {
   return "AClass";
  }
}

这会解决你的直接症状,但我不确定是否能解决你的问题。它有一种特定的代码味道,但在不知道更多的情况下,当我声明XML的概念应该存在于不同的类中,并且将其存在于a和B中违反了单一责任原则时,我可能是错的。基本上,我会从我刚刚收到的信息中知道,为什么不给bas类一个虚拟的GetTagName类,并让继承类覆盖它呢

class A{
public virtual string GetXmlTagName()
  {
   return "AClass";
  }
}

这会解决你的直接症状,但我不确定是否能解决你的问题。它有一种特定的代码味道,但在不知道更多的情况下,当我声明XML的概念应该存在于不同的类中,并且将其存在于a和B中违反了单一责任原则时,我可能是错的。基本上我会从我刚刚收到的信息中知道的

谢谢你的回复。你的文章读起来很有趣。我的问题相当简单,但我很难想出一个好的解决方案:我有几个子类,每个子类都有自己独特的xml标记常量。我在另一个类中有一个泛型方法Load(),该类接受这些子类中的任何一个子类,并将从XmlNode加载该类的实例。Load()需要根据所使用的类型获取xml标记,以便知道要查找哪些xml标记。只有在找到子类的xml标记后,才会实例化子类。我们在这里讨论的类型有多少?两个?三个?几百?还是一个可能无限的数字?谢谢你的回复。你的文章读起来很有趣。我的问题相当简单,但我很难想出一个好的解决方案:我有几个子类,每个子类都有自己独特的xml标记常量。我在另一个类中有一个泛型方法Load(),该类接受这些子类中的任何一个子类,并将从XmlNode加载该类的实例。Load()需要根据所使用的类型获取xml标记,以便知道要查找哪些xml标记。只有在找到子类的xml标记后,才会实例化子类。我们在这里讨论的类型有多少?两个?三个?几百?或者是一个潜在的无界数字?是的,这会起作用,但我需要在实例化类之前获得常量。然后发布的方法GetName将不起作用。您发布的方法接受一个参数T(其中T:A),因此在该方法中,您将始终拥有一个对象(除非您将null作为参数传递)。是的,这将起作用,但我需要T