.Net仲裁运行时类实例和方法调用

时间:2015-07-28 10:52:03

标签: c# .net reflection runtime

我正在寻找一种方法来执行任意类的实例以及属性分配和可能的方法调用.Net,最好是C#。因为任意太宽泛,所以让我告诉你我追求的是什么。

假设我有一个DLL(objects.dll),其中包含:

public class Person
{
    // Field 
    public string name;

    // Constructor that takes no arguments. 
    public Person()
    {
        name = "unknown";
    }

    // Constructor that takes one argument. 
    public Person(string nm)
    {
        name = nm;
    }

    // Method 
    public void SetName(string newName)
    {
        name = newName;
    }

}

public class Table
{
    // Field 
    public int width;
    public int lenth;
    public int height;

    // Constructor that takes no arguments. 
    public Table()
    {
        width = 0;
        length = 0;
        height = 0
    }

    // Constructor that takes three arguments. 
    public Table(int w, int l, int h)
    {
        width = w;
        length = l;
        height = h;
    }

    // Method 
    public void SetWLH(int w, int l, int h)
    {
        width = w;
        length = l;
        height = h;
    }
}

public class Printer
{
    public Printer(){}

    public void printAPerson(Person p)
    {
        //do stuff with p
    }

    public void printATable(Table t)
    {
        // do stuff with t
    }
}

我希望能够实例化上述任何一个类,设置属性值并在运行时从最通用的不同程序中调用方法。例如。让我说我讨厌一个名为myprog.exe的程序,我想能够做到以下

myprog.exe objects.dll人名testname打印机printAPerson 其中:

  • objects.dll是包含所有必需类的dll

  • 人是第一个我将实例化名称是其属性

  • testname是我将分配给此属性的值

  • 打印机是我将用于打印的类

  • printAPerson是我需要使用指定对象作为参数调用的Printer类中的方法。

正如您所看到的,在我使用场景的最佳情况下,在编译时都不会知道对象和类,因此我希望尽可能不进行转换。如果那是不可能的,我将尽我所能。

我已经看到了这个,How to use reflection to call a method and pass parameters whose types are unknown at compile time?,根据我有限的知识,做了我想要的东西减去铸造位或者我可能会弄错。

非常感谢!

2 个答案:

答案 0 :(得分:0)

您对可执行文件输入格式有灵活性吗?如果是这样,你可以通过约定做你想做的事。我会使用像这样的JSON结构来做到这一点:

{
   Command : "",
   Arguments : {
      Argument1 : 0,
      Argument2 : {  }, // can be another complex object
      Argument3 : [] // an empty array maybe ...
     }
}

其中Command类似于“ClassName.MethodName”,Arguments将是一个JSON对象,每个对象属性代表您的方法参数。

在您的可执行文件中,您必须使用库(示例http://www.newtonsoft.com/json)解析此JSON并使用反射来反序列化每个JSON对象参数并调用您的方法。如果你不能让它工作,请让我知道我会试着做一个例子(如果我今晚有时间,因为我现在在工作)。

对于您的情况,您只想打印一个Person类型的对象到打印机?您可以执行如下命令:

{
  Command : "Printer.PrintAPerson",
  Arguments : {
   p : { name : 'george' }
  }
}

如果您想依赖标准协议,请检查JSON-RPC协议:http://json-rpc.org/wiki/specification

答案 1 :(得分:0)

您可以使用dynamic而不是使用反射。但这需要更改Printer类和其他类。你会松开智能感知并编制时间检查。

public class Printer
{
    public Printer() { }

    public void printAPerson(dynamic p)
    {
        //do stuff with p
        Console.WriteLine("Person name: " + p.name);
    }

    public void printATable(dynamic t)
    {
        // do stuff with t
        Console.WriteLine("printATable(Table p) is called");
    }
}

public class TestDynamic
{
    public static void Test()
    {
        // To get the type by name, 
        // the full type name (namespace + type name) is needed
        Type personType = Type.GetType("StackOverflowCodes.Person");
        object personObj = Activator.CreateInstance(personType);

        // Implicit cast to dynamic
        dynamic person = personObj;
        person.SetName("Alan Turing");

        Type printerType = Type.GetType("StackOverflowCodes.Printer");
        object printerObj = Activator.CreateInstance(printerType);

        dynamic printer = printerObj;
        printer.printAPerson(personObj);
    }
}