0

下面的示例显示了意图。该示例正在遍历一个对象数组,并创建一个加载了默认值的相同类型的数组。值本身不需要从一个列表复制到下一个列表。这是列表的“类型克隆”。

下面的代码会为 Activator 产生以下错误:

“System.Int32 不是 GenericTypeDefinition。MakeGenericType 只能在 Type.IsGenericTypeDefinition 为真的类型上调用。”

Activator、CreateInstance 和 MakeGenericType 的细节还是让我有点困惑。

如何更改代码以避免错误?

任何建议,将不胜感激。

    private void Test()
    {
        object[] a = new object[] {100, "Text", new clsMyClass()};
        object[] b = new object[a.Length];

        for (int i = 0; i < a.Length; i++)
        {
            b[i] = Activator.CreateInstance(a[i].GetType().MakeGenericType());
        }

        for (int i = 0; i < b.Length; i++)
        {
            Console.WriteLine(b[i].GetType().ToString());
        }
    }

预期的输出将是:

  • System.Int32
  • 系统字符串
  • MyNamespace.clsMyClass

结果值为:

  • b[0] = 0
  • b[1] = ""
  • b[2] = 新的 clsMyClass
4

1 回答 1

4

删除MakeGenericType(),它将开始工作,使用这个

b[i] = Activator.CreateInstance(a[i].GetType());

MakeGenericType 用于用定义的参数替换泛型参数。例如,如果您的数组将包含List<T>,则调用 a[i].GetType().MakeGenericType(typeof(int))将返回 type List<int>

在您的情况下,我没有看到任何泛型类型,所以我想知道您为什么使用它

另请注意,Activator.CreateInstance只有当类型具有无参数构造函数时,这样的调用才会起作用,例如在string. 你可以string这样处理

for (int i = 0; i < a.Length; i++)
{
   var oType = a[i].GetType();
   if (oType == typeof(string)) 
       b[i] = string.Empty; //or may be null 
   else
       b[i] = Activator.CreateInstance(oType);
}

对于没有无参数构造函数的所有类型,都应该做一些类似的事情。 Activator.CreateInstance(type, parameters...)可以完成这项工作。如果需要,您可以使用反射来调查类型构造函数参数

于 2012-11-29T22:56:42.790 回答