我如何使用Activator.CreateInstance与字符串?

在我的reflection代码中,我遇到了我的通用代码部分的问题。 特别是当我使用一个字符串。

var oVal = (object)"Test"; var oType = oVal.GetType(); var sz = Activator.CreateInstance(oType, oVal); 

例外

 An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll Additional information: Constructor on type 'System.String' not found. 

我试过这个用于测试目的,它也发生在这个单一的衬里

 var sz = Activator.CreateInstance("".GetType(), "Test"); 

我最初写的

 var sz = Activator.CreateInstance("".GetType()); 

但是我得到了这个错误

 Additional information: No parameterless constructor defined for this object. 

如何使用reflection创建字符串?

请记住,字符串类是不可变的。 创建后无法更改。 这就解释了为什么它没有无参数构造函数,它永远不会生成除空字符串之外的有用字符串对象。 这已经在C#语言中提供,它是“”。

相同的推理适用于字符串(String)构造函数。 重复一个字符串是没有意义的,你传递给构造函数的字符串已经是一个非常好的字符串实例。

因此,通过测试字符串大小写来解决您的问题:

 var oType = oVal.GetType(); if (oType == typeof(string)) return oVal as string; else return Activator.CreateInstance(oType, oVal); 

你正试图这样做:

 var sz = new string(); 

尝试编译它,你就会明白你的错误。

你可以尝试:

 var sz = Activator.CreateInstance(typeof(string), new object[] {"value".ToCharArray()}); 

但它看起来没用,你应该直接使用价值……

看起来你正试图调用一个只接受字符串的构造函数 – 并且没有这样的构造函数。 如果你已经有了一个字符串,你为什么要创建一个新字符串? (当你没有提供任何进一步的参数时,你试图调用一个无参数的构造函数 – 它同样不存在。)

请注意, typeof(string)是获取字符串类型引用的更简单方法。

您能否向我们提供更多有关您正在尝试做的事情的更多信息?

String实际上没有将字符串作为输入的构造函数。 有一个构造函数接受一个char数组,所以这应该工作:

 var sz = Activator.CreateInstance ("".GetType (), "Test".ToCharArray ()); 

这就是我在项目中使用的内容。 至于需要创建一种对象类型的实例化并且在设计时不知道,对我来说是正常的。 也许您正在循环访问对象属性,并且您希望动态地实例化所有这些属性。 我有很多次需要创建然后为非实例化的POCO对象赋值…使用下面的代码,您可以使用存储在数据库中的字符串值来实例化对象,或者实例化存储在引用您的库的库中的对象库 – 所以你也可以绕过循环引用错误…希望它有所帮助。

 using System; using System.Collections.Generic; using System.Globalization; using System.Reflection; ///  /// Instantiates an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate /// returns instantiated object ///  ///  ///  public static object Create(string typeAssemblyQualifiedName) { // resolve the type Type targetType = ResolveType(typeAssemblyQualifiedName); if (targetType == null) throw new ArgumentException("Unable to resolve object type: " + typeAssemblyQualifiedName); return Create(targetType); } ///  /// create by type of T ///  ///  ///  public static T Create() { Type targetType = typeof(T); return (T)Create(targetType); } ///  /// general object creation ///  ///  ///  public static object Create(Type targetType) { //string test first - it has no parameterless constructor if (Type.GetTypeCode(targetType) == TypeCode.String) return string.Empty; // get the default constructor and instantiate Type[] types = new Type[0]; ConstructorInfo info = targetType.GetConstructor(types); object targetObject = null; if (info == null) //must not have found the constructor if (targetType.BaseType.UnderlyingSystemType.FullName.Contains("Enum")) targetObject = Activator.CreateInstance(targetType); else throw new ArgumentException("Unable to instantiate type: " + targetType.AssemblyQualifiedName + " - Constructor not found"); else targetObject = info.Invoke(null); if (targetObject == null) throw new ArgumentException("Unable to instantiate type: " + targetType.AssemblyQualifiedName + " - Unknown Error"); return targetObject; } ///  /// Loads the assembly of an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate /// Returns the object type. ///  ///  ///  public static Type ResolveType(string typeAssemblyQualifiedName) { int commaIndex = typeAssemblyQualifiedName.IndexOf(","); string className = typeAssemblyQualifiedName.Substring(0, commaIndex).Trim(); string assemblyName = typeAssemblyQualifiedName.Substring(commaIndex + 1).Trim(); if (className.Contains("[]")) className.Remove(className.IndexOf("[]"), 2); // Get the assembly containing the handler Assembly assembly = null; try { assembly = Assembly.Load(assemblyName); } catch { try { assembly = Assembly.LoadWithPartialName(assemblyName);//yes yes this is obsolete but it is only a backup call } catch { throw new ArgumentException("Can't load assembly " + assemblyName); } } // Get the handler return assembly.GetType(className, false, false); }