读书人

经过反射给对象的对象的属性赋值

发布时间: 2013-01-23 10:44:50 作者: rapoo

通过反射给对象的对象的属性赋值


请问如何通过反射给Integration类中的Config赋值呢?问题和http://q.cnblogs.com/q/45025/类似
代码如下:
class Test
{
public static void GetInfo(string path, string newValue)
{
//load dll
Assembly asm = Assembly.LoadFrom(path);
Type type = asm.GetType("Integration");
PropertyInfo piConfig = type.GetProperty("Config", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Static);
PropertyInfo piName = piConfig.PropertyType.GetProperty("Name");
piName.SetValue(??, Convert.ChangeType(newValue, piName.PropertyType), null);
}
}

class Integration
{
internal static Config Config { get; set; }
}

class Config
{
public string Name { get; set; }

public string URL { get; set; }
}
有大神知道如何解决么?

[解决办法]
SetValue 不就行了吗
[解决办法]
typeof(Integration).GetProperty("Config", BindingFlags.IgnoreCase
[解决办法]
BindingFlags.NonPublic
[解决办法]
BindingFlags.Static).SetValue(null, new Config() { Name = "a", URL = "b" }, null);

[解决办法]
通过spring配置
[解决办法]
无解了,Integration是通过emit实例化的,代码无法获取emit中的对象,不知道那位大神能够看得懂
C# code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

DynamicMethod method = new DynamicMethod("DynamicCreate", destinationType, new Type[] { typeof(IDataRecord) }, destinationType, true);
ILGenerator il = method.GetILGenerator();
LocalBuilder result = il.DeclareLocal(destinationType);
il.Emit(OpCodes.Newobj, destinationType.GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Stloc, result);
il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
for (int i = 0; i < dataRecord.FieldCount; i++)


{
PropertyInfo propertyInfo = null;
<span style="color: #FF0000;">//select Url,[Name] [Config.Name] from [Integration]
//通过.来确定是给对象中对象的属性赋值</span>
string fieldName = dataRecord.GetName(i);
if (fieldName.Contains("."))
{
//获取对象类型
string propertyName = fieldName.Substring(0, fieldName.IndexOf("."));
//得到Config对象
propertyInfo = destinationType.GetProperty(propertyName, BindingFlags.Public
[解决办法]
BindingFlags.Instance
[解决办法]
BindingFlags.IgnoreCase);
object obj = Activator.CreateInstance(propertyInfo.PropertyType);
<span style="color: #FF0000;">propertyInfo.SetValue(il, obj, null);</span>//此处无解了

//propertyInfo.GetSetMethod().Invoke(obj, null);
//获取对象中的子类型
propertyInfo = propertyInfo.PropertyType.GetProperty(fieldName.Substring(fieldName.IndexOf(".") + 1), BindingFlags.Public
[解决办法]
BindingFlags.Instance
[解决办法]
BindingFlags.IgnoreCase);
if (propertyInfo == null)
throw new Exception("没有找到对象");
//throw new Exception(propertyInfo.Name);
}
else
propertyInfo = destinationType.GetProperty(dataRecord.GetName(i),
BindingFlags.Public
[解决办法]
BindingFlags.Instance
[解决办法]
BindingFlags.IgnoreCase);

//以下对属性赋值操作
[解决办法]
你完全搞错了Emit的用法了,使用Emit,就不能用常规的方法来操作,所有操作都必须通过IL来,先把参数压入堆栈,然后调用方法。你都没有压入参数,谈何赋值操作?就你的这个设计理念,改动量很大,虽然可以做到,但不值得,我也不高兴花上几个小时去调试那代码,Emit的代码是最难调试的,不实际运行是检测不出错误的。
你这里应该用简单类型操作,参考Dapper,看它是如何做到复杂类型的嵌套的,我博客里也有Dapper的代码,你也可以Google搜索Dapper,那个才是最佳做法。
[解决办法]

引用:
引用:引用:无解了,Integration是通过emit实例化的,代码无法获取emit中的对象,不知道那位大神能够看得懂
C# code?123456789101112131415161718192021222324252627282930313233DynamicMethod method = n……


只是代码提取出来,并没有改变原有的通用性,如下:

private void InitIntegration(Type destinationType, string fieldName, object result)
{


PropertyInfo propertyInfo = null;
//获取对象类型
string propertyName = fieldName.Substring(0, fieldName.IndexOf("."));
//得到Config对象
propertyInfo = destinationType.GetProperty(propertyName, BindingFlags.Public
[解决办法]
BindingFlags.Instance
[解决办法]
BindingFlags.IgnoreCase);
object obj = Activator.CreateInstance(propertyInfo.PropertyType);
propertyInfo.SetValue(result, obj, null);//此处无解了,如何得到Emit中实例化的对象呢?
//propertyInfo.GetSetMethod().Invoke(obj, null);//报类型不匹配,不知为何
//获取Config对象中的Name属性,如果得到propertyInfo,后面Emit直接赋值即可
propertyInfo = propertyInfo.PropertyType.GetProperty(fieldName.Substring(fieldName.IndexOf(".") + 1), BindingFlags.Public
[解决办法]
BindingFlags.Instance
[解决办法]
BindingFlags.IgnoreCase);
if (propertyInfo == null)
throw new Exception("没有找到对象");
//throw new Exception(propertyInfo.Name);
}



然后原来的代码,改为:
 

读书人网 >C#

热点推荐