C# 带字符串的Activator.CreateInstance
我试图从字段名匹配的另一个列表中填充一个通用列表C# 带字符串的Activator.CreateInstance,c#,generics,activator,C#,Generics,Activator,我试图从字段名匹配的另一个列表中填充一个通用列表,类似下面未测试的伪代码。我遇到的问题是T是一个字符串,例如,它没有无参数构造函数。我曾尝试将字符串直接添加到结果对象,但这给了我一个明显的错误——字符串不是T类型的。有没有解决这个问题的方法?谢谢你的指点 public static List<T> GetObjectList<T, U>(List<U> givenObjects) { var result = new List&
public static List<T> GetObjectList<T, U>(List<U> givenObjects)
{
var result = new List<T>();
//Get the two object types so we can compare them.
Type returnType = typeof(T);
PropertyInfo[] classFieldsOfReturnType = returnType.GetProperties(
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.Public);
Type givenType = typeof(U);
PropertyInfo[] classFieldsOfGivenType = givenType.GetProperties(
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.Public);
//Go through each object to extract values
foreach (var givenObject in givenObjects)
{
foreach (var field in classFieldsOfReturnType)
{
//Find where names match
var givenTypeField = classFieldsOfGivenType.Where(w => w.Name == field.Name).FirstOrDefault();
if (givenTypeField != null)
{
//Set the value of the given object to the return object
var instance = Activator.CreateInstance<T>();
var value = field.GetValue(givenObject);
PropertyInfo pi = returnType.GetProperty(field.Name);
pi.SetValue(instance, value);
result.Add(instance);
}
}
}
return result;
}
公共静态列表GetObjectList(列表给定对象)
{
var result=新列表();
//获取这两种对象类型,以便比较它们。
类型returnType=类型(T);
PropertyInfo[]classFieldsOfReturnType=returnType.GetProperties(
BindingFlags.Instance|
BindingFlags.Static|
BindingFlags.NonPublic|
(公众),;
类型givenType=typeof(U);
PropertyInfo[]classFieldsOfGivenType=givenType.GetProperties(
BindingFlags.Instance|
BindingFlags.Static|
BindingFlags.NonPublic|
(公众),;
//遍历每个对象以提取值
foreach(在givenObjects中变量givenObject)
{
foreach(classFieldsOfReturnType中的变量字段)
{
//查找名称匹配的位置
var givenTypeField=classFieldsOfGivenType.Where(w=>w.Name==field.Name).FirstOrDefault();
if(givenTypeField!=null)
{
//将给定对象的值设置为返回对象
var instance=Activator.CreateInstance();
var值=field.GetValue(givenObject);
PropertyInfo pi=returnType.GetProperty(field.Name);
pi.SetValue(实例,值);
结果.添加(实例);
}
}
}
返回结果;
}
如果T
是string
,并且您已经创建了自定义代码来将givenObject
转换为字符串,则只需执行to对象
即可将其添加到列表中
:
publicstaticlist GetObjectList2(List-givenObjects),其中T:class
{
var result=新列表();
if(typeof(T)=typeof(string))
{
foreach(在givenObjects中变量givenObject)
{
var instance=givenObject.ToString();//自定义字符串转换。
添加((T)(对象)实例);
}
}
其他的
{
//照旧进行
}
返回结果;
}
顺便说一句,对于与U
中的属性名称匹配的T
的每个属性以及givenObjects
中的每个项目,您正在将的实例
添加到结果
。也就是说,如果givenObjects
是长度为1的列表,T
是一个具有10个匹配属性的类,result
可能会以10个条目结束。这看起来不对。此外,你还需要注意
作为这种方法的替代,考虑使用或序列化您的<代码>列表>代码> Json.NET的JSON,然后反序列化为<代码>列表< /代码> .< /P>查看<代码> FrastServices。小心使用!实际上GetUninitializedObject不适用于字符串(
ArgumentException:无法创建未初始化的字符串
),但是它应该适用于没有默认构造函数的其他类,而且我真的想不出通过此函数放置字符串列表的理由。哈?cast不会更改底层对象的类型,您可以认为,如果它是一个值磁带,装箱可能会被视为类型更改,但对于引用类型,这是非常明确的。换句话说,如果某个对象出现运行时异常(与编译时错误相反),则强制转换引用类型的对象将无法解决该问题。@zespri-Brent写道:“我曾尝试将字符串直接添加到结果对象,但这给了我一个明显的错误——字符串不是T类型。”因此,Brent已经手动创建了一个与输入对象相对应的字符串
,但编译器正在抱怨,因为它无法添加到列表
,但是t
是字符串
,因此不需要真正的转换,只需一次转换。这很有效,dbc,谢谢!我确实试着把绳子拉到T上,但显然不行。将字符串投射到对象然后再投射到T的技巧非常有用。很高兴知道。好的,让我投票给你然后=)我错过了这确实是编译时错误。
public static List<T> GetObjectList2<T, U>(List<U> givenObjects) where T : class
{
var result = new List<T>();
if (typeof(T) == typeof(string))
{
foreach (var givenObject in givenObjects)
{
var instance = givenObject.ToString(); // Your custom conversion to string.
result.Add((T)(object)instance);
}
}
else
{
// Proceed as before
}
return result;
}