从字符串名称在程序集中创建类实例

Arc*_*ian 2 .net c# .net-assembly

我不确定这是否可行,而且我在C#.NET中使用程序集还是很新的.

我想要做的是在提供该类的字符串名称时创建一个类的实例.像这样的东西:

using MyAssembly;

namespace MyNameSpace
{
     Class MyClass
     {
          int MyValue1;
          int MyValue2;

          public MyClass(string myTypeName)
          {
               foreach(Type type in MyAssembly)
               {
                    if((string)type == myTypeName)
                    {
                         //create a new instance of the type
                    }
               }
               AssignInitialValues(//the type created above)
          }

          //Here I use an abstract type which the type above inherits from
          private void AssignInitialValues(AbstractType myClass)
          {
               this.value1 = myClass.value1;
               this.value2 = myClass.value2;
          }
      }
 }
Run Code Online (Sandbox Code Playgroud)

显然你无法将字符串与类型进行比较,但它说明了我正在尝试做的事情:在提供的字符串中创建一个在不同程序集中找到的类型.

有什么想法吗?


编辑:

尝试后:

var myObject = (AbstractType) Activator.CreateInstance(null, myTypeName);
AssignInitialValues(myObject);
Run Code Online (Sandbox Code Playgroud)

我收到了一些错误:

  • 可访问性不一致:参数类型"MyAssembly.AbstractType"比方法"MyNameSpace.MyClass.AssignInitialValues(MyAssembly.AstractType)"更难访问
  • 'MyAssembly.AstractType'由于其保护级别而无法访问
  • 找不到类型或命名空间名称"MyAssembly"(您是否缺少using指令或程序集引用?)
  • 找不到类型或命名空间名称'AbstractType'(您是否缺少using指令或程序集引用?)

不确定为什么它找不到装配; 我添加了对程序集的引用,并在程序集中使用了使用指令作为命名空间.至于保护级别,它是调用类(或者更确切地说是类的构造函数),它们只能是公共的.

关于问题所在的任何线索?


更新:

在浏览了几篇关于SO的文章后,我发现了这个问题:https://stackoverflow.com/a/1632609/360627AbstractType公共课程解决了不一致的可访问性问题.

新的编译器错误是这样的:

无法将类型'System.Runtime.Remoting.ObjectHandle'转换为'MyAssembly.AbstractType'

它引用的行是这一行:

var myObject = (AbstractType) Activator.CreateInstance(null, myTypeName);
Run Code Online (Sandbox Code Playgroud)

使用.Unwrap()get我的过去这个错误,我认为这是正确的方法(不确定).但是,在运行程序时,我会在调用此代码时获得TypeLoadException.

TypeLoadException:无法从程序集"MyNameSpace"加载类型"AbstractType"...

我马上发现它所寻找的类型是正确的,但它正在查看的装配是错误的.查找该Activator.CreateInstance(String, String)方法显示null为第一个参数意味着该方法将在执行程序集中查找.这与原始帖子中所要求的行为相反.

我尝试使用MyAssembly作为第一个参数,但这会产生错误:

'MyAssembly'是'命名空间',但用作'变量'

认为这是因为MyAssembly不是一个字符串.但是,如果我尝试'MyAssembly'我得到以下编译器错误:

  • 字符文字中的字符太多
  • 'System.Activator.CreateInstance(System.ActivationContext,string [])'的最佳重载方法匹配有一些无效的参数
  • 参数1:无法从'char'转换为'System.ActivationContext'
  • 参数2:无法从'string'转换为'string []'

在我看来,它试图使用错误的重载.

有关如何解决此问题的任何想法?

Bro*_*ass 8

如果您拥有类型的完全限定名称,则根本不需要此foreach循环:

var myObject = (SomeBaseType) Activator.CreateInstance(null, myTypeName);
Run Code Online (Sandbox Code Playgroud)


Cod*_*ist 6

有很多方法可以满足您的需求.不是最好的表现:

Activator.CreateInstance(null, myTypeName);
Run Code Online (Sandbox Code Playgroud)

你也可以用这个:

var ci = Type.GetType(myTypeName).GetConstructor(Type.EmptyTypes);
var myTypeInstance = ci.Invoke(new object[]{})
Run Code Online (Sandbox Code Playgroud)