2011-03-25 149 views
0

下面是从类对象中获取属性值的方法。我怎样才能通过传递类名字符串来实例化类。实例化后,我想使用在同一页面上可用的方法'LoadFromXmlData()'。这可以做到吗?使用反射实例化类并调用方法

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

     } 

    } 

我将如下加载我的DLL。在这之后我应该如何继续。请帮忙,我对反思很陌生。

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

感谢

+1

为什么这个可怕的命名风格?它使代码不可读。 – 2011-03-25 16:46:27

+0

对于命名风格感到抱歉。如果有其他条件,我的实际功能会更大。我刚刚发布了一些示例函数,我试图实现 – San 2011-03-25 16:57:04

+0

命名风格很常见,但是你想实现什么?我不明白你为什么使用反射。如果你必须处理大的if/else条件,你应该尝试找到更好的解决方案来解决你的问题。 – Zebi 2011-03-25 17:08:17

回答

4

我不是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(); 
    } 

这将调用LoadFromXmlData与要加载的类的类型和一些XML数据。


为了避免调用LoadFromXmlData方法的反射,你应该创建所有动态加载的类必须实现一个接口:

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

然后调用该方法可以简化成这样:

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

如果您正在使用C#4,你可以使用动态关键字对mplify反射工作:

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

,如果它是一个实例方法,你可以做

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()}); 
+0

谢谢,但我无法声明'Class1 _Class1;'我已经在上面的示例中展示过了。该类还需要通过使用传递给该方法的className字符串来动态实例化。 – San 2011-03-25 18:15:43

+0

@san您是否在编译时引用了具有该类的程序集? – 2011-03-25 18:53:15

+0

是的我引用编译时具有该类的程序集 – San 2011-03-26 16:01:05

0

我相信你需要做这样的事情:

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

“Namespace.Class1 “是装配合格的。例如,对于一类的程序集限定的名称可能是这样的:

TopNamespace.SubNameSpace.ContainingClass + NestedClass, MyAssembly程序,版本= 1.3.0.0, 文化=中立, 公钥= b17a5c561934e089

0

我想你需要使用Activator.CreateInstance()方法创建类的实例。你可以直接在对象中调用方法。

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