根据字符串中的类名创建对象

本文关键字:创建对象 字符串 | 更新日期: 2023-09-27 18:29:03

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

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

根据字符串中的类名创建对象

这对我来说很有效,但接口将是更好的方法:

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

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

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

Perhap您可以首先获得正确的类型来创建实例。

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