如何创建访问集合元素的表达式?
发布网友
发布时间:2022-04-10 08:40
我来回答
共2个回答
热心网友
时间:2022-04-10 10:09
这问题有点意思
首先,你那写法叫索引器(Indexer),在.NET中索引器跟属性(Property)实际上是一回事儿,索引器只是有参数的属性罢了,普通属性是无参数的,了解这点之后就简单了,只需要找到这的属性即可
其次,如何获取这个特殊属性?有两个方法:
一,GetProperty("Item"),这能获取大部分属性,除开DefaultMemberAttribute自定义的,比如string就得用GetProperty("Chars")
二,用GetDefaultMembers方法,这个适用面更广,但是代码量更多
最后,获取属性之后,就可以使用GetGetMethod和GetSetMethod来获取其取值和赋值的内部方法
public static LambdaExpression GetIndexGetExp<objT, indexT>()
{
Type objType = typeof(objT), indexType = typeof(indexT);
var defaultMembers = objType.GetDefaultMembers();
PropertyInfo propInfo = null;
foreach (var mem in defaultMembers)
{
if (mem.MemberType == MemberTypes.Property)
{
propInfo = (PropertyInfo)mem;
if (propInfo == objType.GetProperty(propInfo.Name, new[] { indexType }))
{
break;
}
}
}
var getMethod = propInfo.GetGetMethod();
var objParm = Expression.Parameter(objType);//实例对象参数
var valueParm = Expression.Parameter(indexType);//索引器参数
var getExp= Expression.Call(objParm, getMethod, new[] { valueParm });
var lambda=Expression.Lambda(getExp, new[] { objParm, valueParm });
return lambda;
}
public static LambdaExpression GetIndexSetExp<objT, indexT>()
{
Type objType = typeof(objT), indexType = typeof(indexT);
var defaultMembers = objType.GetDefaultMembers();
PropertyInfo propInfo = null;
foreach (var mem in defaultMembers)
{
if (mem.MemberType == MemberTypes.Property)
{
propInfo = (PropertyInfo)mem;
if (propInfo == objType.GetProperty(propInfo.Name, new[] { indexType }))
{
break;
}
}
}
var setMethod = propInfo.GetSetMethod();
var objParm = Expression.Parameter(objType);//实例对象参数
var indexParm = Expression.Parameter(indexType);//索引器参数
var valueParm = Expression.Parameter(propInfo.PropertyType);//索引器值
var setExp = Expression.Call(objParm, setMethod, new[] { indexParm, valueParm });
var lambda = Expression.Lambda(setExp, objParm, indexParm, valueParm);
return lambda;
}
调用及结果
var stringFunc = GetIndexGetExp<string, int>().Compile();
string s = "abcd";
Console.WriteLine(stringFunc.DynamicInvoke(s, 0));
//a
var arrFunc = GetIndexSetExp<List<int>, int>().Compile();
var arr = new List<int> { 1, 2, 3, 4, 5 };
arrFunc.DynamicInvoke(arr, 0, 2);
Console.WriteLine(string.Join(",", arr));
//2,2,3,4,5
热心网友
时间:2022-04-10 11:27
实现IDictionary接口就行了啊
MSDN范例:http://msdn.microsoft.com/zh-cn/library/system.collections.idictionary(VS.80).aspx