Создание класса с использованием отражения и вызов метода - PullRequest
0 голосов
/ 25 марта 2011

Ниже приведен мой метод получения значения свойства из объекта класса. Как я могу добиться того же, создавая экземпляр класса, передавая имя класса как String. После создания экземпляра я хочу использовать метод 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);

Спасибо

Ответы [ 4 ]

4 голосов
/ 25 марта 2011

Я не уверен на 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, вы можете использовать динамическое ключевое слово для упрощения работы с отражением:

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 голосов
/ 25 марта 2011

если это метод экземпляра, вы можете сделать

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 голосов
/ 25 марта 2011

Я думаю, вам нужно создать экземпляр класса, используя метод 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");
    }
}
0 голосов
/ 25 марта 2011

Полагаю, вам нужно будет сделать что-то вроде этого:

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

"Namespace.Class1" является квалифицированным для сборки.Например, полное имя сборки для класса может выглядеть так:

TopNamespace.SubNameSpace.ContainedClass + NestedClass, MyAssembly, Version = 1.3.0.0, Culture = нейтральный, PublicKeyToken = b17a5c561934e089

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...