简体   繁体   English

使用反射实例化类并调用方法

[英]Instantiating class using reflection and calling a method

Below is my method to get a property value from a class object. 下面是我从类对象获取属性值的方法。 How can I achieve the same by instantiating the class by passing the class name as String. 我如何通过将类名作为String传递来实例化该类,从而实现相同目的。 After instantiating, I want to use the method 'LoadFromXmlData()' which is available on the same page. 实例化之后,我想使用在同一页面上可用的方法“ LoadFromXmlData()”。 Can this be done? 能做到吗?

 private string GetPropertyValue(string propName, string className)
    {
      Class1 _Class1;
      Class2 _Class2;
      Class3 _Class3; 

        if (className.Equals("Class1"))
        {

         _Class1 = new Class1();
         _Class1 = (Class1)Class1.LoadFromXmlData(typeof(Class1), myData.ToString());

          return _Class1.GetType().GetProperty(propName).GetValue(_Class1,   null).ToString();
        }
        else if (ActionClassName.Equals("TicketActionDef"))
        {
         _Class2 = new Class2();
         _Class2 = (Class2)Class2.LoadFromXmlData(typeof(Class2), myData.ToString());

         return __Class2.GetType().GetProperty(propName).GetValue(_Class2, null).ToString();
        }
        else
        {
         _Class3 = new Class3();
         _Class3 = (Class1)Class1.LoadFromXmlData(typeof(Class3), myData.ToString());

         return __Class3.GetType().GetProperty(propName).GetValue(_Class3, null).ToString();

        }

    }

I will load my DLL as below. 我将如下加载我的DLL。 How should I proceed after this. 此后我应该如何进行。 Please help, I am very new to reflection. 请帮助,我对反思非常陌生。

 Assembly assembly = Assembly.GetAssembly(typeof(MyAdapter));
 MyAdapter currentEventObject = (MyAdapter)assembly.CreateInstance(className);

Thanks 谢谢

I'm not 100% sure I understand the full scope of what you're trying to achieve, but in order to instantiate a named class (make sure to include the fully qualified name; fullNamespace.className) and call a method and a property on it you can do it like this: 我不是100%确定我了解您要实现的全部范围,但是为了实例化命名类(确保包括完全限定的名称; fullNamespace.className)并调用方法和属性在它上面,你可以这样:

    private static string GetPropertyValue(Assembly assembly, string className, 
        string propertyName)
    {
        object instance = assembly.CreateInstance(className);
        Type classType = instance.GetType();
        MethodInfo method = classType.GetMethod("LoadFromXmlData");
        method.Invoke(instance, new object[] { classType, myData });
        PropertyInfo property = classType.GetProperty(propertyName);
        return property.GetValue(instance, null).ToString();
    }

This will call the LoadFromXmlData with the type of the class to be loaded and some xml data. 这将使用要加载的类的类型和一些xml数据调用LoadFromXmlData。


In order to avoid the reflection for calling the LoadFromXmlData method, you should create an interface that all dynamically loaded types must implement: 为了避免反射调用LoadFromXmlData方法,您应该创建一个接口,所有动态加载的类型都必须实现:

interface IXmlLoadable
{
   void LoadFromXmlData(Type type, string data);
}

Then the method call could be simplified into this: 然后可以将方法调用简化为:

((IXmlLoadable)instance).LoadFromXmlData(classType, myData));

If you are using C# 4, you could use the dynamic keyword to simplify the reflection work: 如果使用的是C#4,则可以使用dynamic关键字简化反射工作:

private static string GetPropertyValue(Assembly assembly, string className,     
   string propertyName)
{
        dynamic instance = assembly.CreateInstance(className);
        Type classType = instance.GetType();
        instance.LoadFromXmlData(classType, "<xml></xml>");
        PropertyInfo property = classType.GetProperty(propertyName);
        return property.GetValue(instance, null).ToString();
}

if it's an instance method, you can do 如果是实例方法,则可以

Object _Class1 = Type.GetType("Class1").GetConstructor(new Type[0]).Invoke(null);
Type.GetType("Class1").GetMethod("LoadFromXmlData" typeof (Class1).GetMethod("LoadFromXmlData").Invoke(_Class1, new[]{myData.ToString()});

I believe you would need to do something like this: 我相信您将需要执行以下操作:

Type.GetType("Namespace.Class1").GetConstructor(new Type[] {}).Invoke(null);

"Namespace.Class1" is the assembly-qualified. “ Namespace.Class1”是程序集限定的。 For example, the assembly-qualified name for a class might look like this: 例如,一个类的程序集限定名称可能看起来像这样:

TopNamespace.SubNameSpace.ContainingClass+NestedClass, MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089 TopNamespace.SubNameSpace.ContainingClass + NestedClass,MyAssembly,版本= 1.3.0.0,文化=中性,PublicKeyToken = b17a5c561934e089

I think you need to create the instance of the class using Activator.CreateInstance() method. 我认为您需要使用Activator.CreateInstance()方法创建该类的实例。 And you can call the method directly in the object. 您可以直接在对象中调用该方法。

class Program
{
    static void Main(string[] args)
    {
        Assembly asm = Assembly.GetExecutingAssembly();
        Sample s1 = Activator.CreateInstance(typeof(Sample)) as Sample;
        s1.SayHello();
    }
}

public class Sample
{
    public void SayHello()
    {
        Console.WriteLine("Hello World");
    }
}

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

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