objectType request = factory.create<objectType>();
public class factory
{
public static T create<T>() where T : new()
{
T obj = new T();
PropertyInfo propertyInfo = obj.GetType().GetProperty("client_no");
propertyInfo.SetValue(obj, CLIENT_NUMBER, null);
return (T)Convert.ChangeType(obj, typeof(T));
}
}
我正在创建一个设置2个对象属性的通用工厂fn()。
这些属性在我想要初始化的所有对象中都是一致的。
1)我如何调用我的函数
objectType request = factory.create<objectType>(); // <-- This works
1b)如果我愿意,可以从这里开始,我可以执行以下操作,但是在我的所有对象中都是重复的额外代码
request.client_no = CLIENT_NUMBER;
2)下面是我的工厂fn()
public static T create<T>() where T : new()
{
T obj = new T();
// Here is where I am having trouble setting client_no I will explain in #3
return (T)Convert.ChangeType(obj, typeof(T)); // <-- This works returns generic type
}
3)我尝试过PropertyInfo来设置对象属性,如下所示
PropertyInfo propertyInfo = obj.GetType().GetProperty("client_no");
propertyInfo.SetValue(obj, CLIENT_NUMBER, null);
我也试过this
obj.GetType().GetProperty("client_no").SetValue(obj, CLIENT_NUMBER, null);
我试过了
T obj = new T();
var t = typeof(T);
var prop = t.GetProperty("client_no");
prop.SetValue(obj, CLIENT_NUMBER);
4)这是我收到的错误
对象引用未设置为对象的实例
因此需要进一步研究。第三方对象属性没有getter和setter {get; set;}这就是为什么GetType()&amp; SetValue()不起作用。
我的同事指出该财产是一项单一的任务 这就是我们能做到的原因
request.client_no = CLIENT_NUMBER;
所以我的问题是如何设置这些属性?
答案 0 :(得分:2)
使用反射,您可以执行以下操作:
public objectName updateAccountData(int accountId, Dictionary<string,string> accountData)
{
var request = new objectName();
var t = typeof(objectName);
foreach (var k in accountData)
{
var prop = t.GetProperty(k.Key); // you might want to check property exists before trying to set it
prop.SetValue(request,k.Value);
}
return request;
}
这假定您的objectName
类已经具有填充所需的所有属性。
请注意,反射比直接访问属性要慢,因此如果此代码位于应用程序的性能关键部分,则可能是一个问题(对其进行配置)。可以很容易地应用几个明显的优化。例如,您可以将PropertyInfo
中检索到的所有GetProperty
个对象存储在Dictionary<string,PropertyInfo>
中,以避免不断查找它们。更复杂的是,您实际上可以使用表达式树来构建和编译表达式以进行属性访问。
对于t.GetField(k.Key)
的{{1}}替换字段{/ 1}。
如果您不知道它是字段或属性(或两者兼而有之),那么您可以使用GetProperty
然后检查GetMember
来决定
答案 1 :(得分:1)
我看到了接受的答案,但是,这是另一种不涉及直接调用反射而是使用DLR的方法。
public static T create<T>() where T : new()
{
T obj = new T();
((dynamic)obj).client_no = CLIENT_NUMBER;
return obj;
}
MSDN Dynamic Language Runtime Overview
这里必不可少的部分是,编译器不会自己编写反射调用,而是会处理它。上面的链接讨论了使用它直接进行反射调用的好处。
答案 2 :(得分:0)
我的主要问题是错误理解,我试图设置的项目不是属性,而是一个字段。
为了更好地了解差异,您可以查看this。
我设置了通用
的字段类型public static T create<T>() where T : new()
{
T obj = new T();
Type myType = typeof(T);
FieldInfo myFieldInfo = myType.GetField("client_no");
myFieldInfo.SetValue(obj, CLIENT_NUMBER);
return obj;
}
特别感谢@MattBurland带领我朝着正确的方向前进。