我需要调用静态类的方法。此类仅在运行时已知(它是System.Type变量)。我知道我的方法是在“MyObject”类中实现的。我该如何调用这种方法?代码说明了我需要做的事情如下。它可能看起来有点变态,但我发誓,我会将它用于良好的目的,不会让宇宙崩溃。
public class MyObject
{
public static string ReturnUsefulStuff()
{
return "Important result.";
}
}
public class MyChildObject: MyObject
{
// Hey! I know about ReturnUsefulStuff() method too!
}
public class App
{
public void Main()
{
// The following type isn't supposed to be known at compile time.
// Except that it will always be MyObject type or its descendent.
Type TypeOfMyObject = typeof(MyChildObject);
// My erotic fantasy below. That line doesn't actually work for static methods
string Str = (TypeOfMyObject as MyObject).ReturnUsefulStuff();
// I know that type has this method! Come on, let me use it!
MessageBox.Show(Str);
}
}
在Delphi中,这可以通过声明
来实现// ...
// interface
Type TMyObjectClass = class of TMyObject;
// ...
// implementation
ClassVar := TMyChildObject;
Str := TMyObjectClass(ClassVar).ReturnUsefulStuff();
这要归功于Delphi的“类”构造。编译器知道TMyObject具有“ReturnUsefulStuff”并且TMyChildObject是从它派生的,并且它还具有ClassVar中类的引用。这就是所需要的一切。 C#没有“class of”的概念,它只有The One System.Type(几乎不会)统治它们。 有什么建议?我会被迫使用各种丑陋的反射技术吗?
答案 0 :(得分:1)
您的代码存在误解:
Delphi具有“类”的概念,这意味着字段/变量可以为类本身保留引用。 .net clr没有这个概念。在运行时的.Net中,您可以查询有关特定类型的信息。当您致电obj.GetType()
时,您会收到一个Type
对象,其中包含有关该类型的信息。然而Type
不像Delphi那样是类本身,它只是一个包含大量信息的常规对象。
这就是为什么这在.net:
中是非法的// TypeOfMyObject is a object of the class Type, which MyObject does not inherit.
(TypeOfMyObject as MyObject).ReturnUsefulStuff();
所以,是的,在这种情况下,你必须使用反射。
var method = typeOfMyObject.GetMethod("ReturnUsefulStuff",
BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
var result = method.Invoke(null, null);
答案 1 :(得分:0)
使用null作为目标对象实例使用TypeOfMyObject.GetMethod("ReturnUsefulStuff").Invoke(...)
(请参阅http://msdn.microsoft.com/en-us/library/05eey4y9.aspx和http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx)
答案 2 :(得分:0)
Type typeOfMyObject = typeof(MyChildObject);
MethodInfo method = typeOfMyObject.GetMethod("ReturnUsefulStuff", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
object result = method.Invoke(null, null);
MessageBox.Show(result.ToString());