2

我需要调用一个静态类的方法。此类仅在运行时已知(它是 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# 没有“类”的概念,它只有 The One System.Type 将(几乎)统治它们。有什么建议么?我会被迫使用各种丑陋的反射技术吗?

4

3 回答 3

1

使用TypeOfMyObject.GetMethod("ReturnUsefulStuff").Invoke(...)null 作为目标对象实例(参见http://msdn.microsoft.com/en-us/library/05eey4y9.aspxhttp://msdn.microsoft.com/en-us/library/a89hcwhh.aspx

于 2012-08-20T15:14:49.937 回答
1
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());
于 2012-08-20T15:20:21.757 回答
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);
于 2012-08-20T15:35:07.793 回答