从字符串中的类名创建对象

时间:2013-08-27 00:46:38

标签: c# .net object reflection

我有100个类都有类似的签名方法,只是它们的内部定义不同。我将传递一个类名作为字符串,我需要创建该类型的对象并调用方法。我知道我可以使用“Activator.CreateInstance”但不确定在这种情况下究竟如何。例如,假设我有一个名为Calculator1到Calculator100的类,我不知道如何根据类名字符串在第二行中强制转换它。

  ObjectHandle handle = Activator.CreateInstance("NameSpaceCalculator", "Calculator1");
  var Calculator = (Calculator1)handle.Unwrap();

3 个答案:

答案 0 :(得分:1)

您可以使用定义了Unwrap()方法的公共接口并将其强制转换为该接口,也可以使用反射来查找Unwrap方法并调用它。

除非您在运行时加载程序集并且不能在其中使用编译时引用的接口,否则我会使用第一个选项,因为对于这种情况,反射速度很慢且过于复杂。

答案 1 :(得分:1)

Perhap你可以先创建正确的类型创建实例。

public CalculatorBase CreateClass(string typeName)
{
    var type = Type.GetType(string.Format("NameSpaceCalculator.{0}",typeName));
    return (CalculatorBase)Activator.CreateInstance(type);
}

答案 2 :(得分:1)

这对我有用,但接口是更好的方法:

void Main()
{
    var x = CreateClass("A");
    x.Unwrap();
}

public BaseC CreateClass(string typeName)
{
    var type = Type.GetType(string.Format("MyNamespace.{0}",typeName);
    return (BaseC)Activator.CreateInstance(type);
}


public class A : BaseC
{
    public override void Unwrap()
    {
        Console.WriteLine("A");
    }
}

public class B : BaseC
{
    public override void Unwrap()
    {
        Console.WriteLine("B");
    }
}

public class BaseC
{
    public virtual void Unwrap()
    {
        Console.WriteLine("BaseC");
    }
}


//// Here is the approach with an Interface (note that overrides and virtual declaration needed. 





void Main()
    {
        var x = CreateClass<IBase>("MyNamespace","A");
        x.Unwrap();
    }

    public T CreateClass<T>(string classNamespace, string typeName) where T : class
    {
        var type = Type.GetType(string.Format("{0}.{1}",classNamespace, typeName));
        return (T)Activator.CreateInstance(type);
    }


    public class A : IBase
    {
        public void Unwrap()
        {
            Console.WriteLine("A");
        }
    }

    public class B : IBase
    {
        public void Unwrap()
        {
            Console.WriteLine("B");
        }
    }

    public interface IBase
    {
        void Unwrap();
    }