简体   繁体   English

.Net套利运行时类实例化和方法调用

[英].Net arbitratry runtime class instantion and method calling

I am looking for a way to do arbitrary class instantion as well as attribute assignement and possibly method calling in .Net and preferrably C#. 我正在寻找一种方法来进行任意的类实例化以及属性分配,并可能在.Net(最好是C#)中进行方法调用。 Since arbitrary is too broad a word let me tell you what I am after. 由于随意性太宽泛,所以让我告诉你我的追求。

Let's say I have a DLL (objects.dll) that contains: 假设我有一个包含以下内容的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
    }
}

I want to be able to instantiate either of the classes above, set attribute values and call methods at runtime from a different program in the most generic possible. 我希望能够实例化以上任何一个类,并在运行时从其他程序中以最通用的方式设置属性值和调用方法。 eg. 例如。 lets say I hame a programm called myprog.exe, i want to be able to do the following 可以说我有一个名为myprog.exe的程序,我希望能够执行以下操作

myprog.exe objects.dll Person name testname Printer printAPerson where: myprog.exe objects.dll人员名称testname打印机printAPerson其中:

  • objects.dll is the dll that contains all required classes objects.dll是包含所有必需类的dll

  • Person is the first I will instantiate name is its attribute 人是我首先要实例化的名称是它的属性

  • testname is the value I will assign to this attribute testname是我将分配给该属性的值

  • Printer is the class I will use for printing 打印机是我将用于打印的课程

  • printAPerson is the method in the Printer class I need to call with the specified object as a parameter. printAPerson是我需要使用指定对象作为参数调用的Printer类中的方法。

As you can see, in the best case for my use scenario, neither of the objects and classes are/will be known at compile time so I would like to be as non-casting as possible. 如您所见,在最适合我的使用场景的情况下,在编译时都不知道/不会知道对象和类,因此我希望尽可能地不进行广播。 If that is not possible I will take what I can. 如果那不可能,我会尽我所能。

I have seen this, How to use reflection to call a method and pass parameters whose types are unknown at compile time? 我已经看到了, 如何使用反射来调用方法并传递在编译时类型未知的参数? , which to my limited knowledge kind of does what I want minus the casting bits or I could be mistaken. ,据我所知,它只是做我想要的减去铸模位的事情,否则我可能会误会。

Thanks a lot! 非常感谢!

Are you flexible concerning your executable input format? 您对可执行输入格式是否灵活? If so, you could do what you want by having a convention. 如果是这样,您可以通过约定来做您想做的事情。 I would do this using a JSON structure like this one: 我将使用这样的JSON结构进行此操作:

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

Where Command would be something like "ClassName.MethodName", Arguments will be a JSON object that each object property represents your method parameter. 其中Command类似于“ ClassName.MethodName”,参数将是一个JSON对象,每个对象属性代表您的方法参数。

In your executable, you must parse this JSON using a library (example http://www.newtonsoft.com/json ) and use reflection to deserialize every JSON object parameter and call your method. 在可执行文件中,您必须使用库(例如http://www.newtonsoft.com/json )解析此JSON,并使用反射反序列化每个JSON对象参数并调用您的方法。 If you cannot get it work, please let me know I will try to make an example (if I will have time, this night because I am at work right now). 如果您无法使它正常工作,请告诉我,我将尝试举一个例子(如果今天晚上我有时间,因为我现在正在工作)。

For your case you just want to print an object of type Person to the printer right? 对于您的情况,您只想在打印机上打印“人”类型的对象? You could execute a command like this: 您可以执行以下命令:

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

If you want to rely on a standard protocol, please check the JSON-RPC protocol: http://json-rpc.org/wiki/specification 如果要依赖标准协议,请检查JSON-RPC协议: http : //json-rpc.org/wiki/specification

Instead of using Reflection you could use dynamic . 除了使用Reflection之外,您还可以使用dynamic But this requires that the Printer class and others are changed. 但这需要更改Printer类和其他类。 And you would loose intellisense and compile time checks. 并且您将失去智能感知并编译时间检查。

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM