从 Func转换成员访问函数到 Func
我正在尝试使用流畅的 nhibernate 创建动态基础映射。
我正在做的是通过 BaseMap< 进行签入T> : 类映射< T>例如: (typeof(ICategorizedEntity).IsAssignableFrom(typeof(T)))
如果是这样,我想映射一个名为“Category”的属性,它属于 ICategorizedEntity 的接口,但 Map(Func) 函数只接受 T 的属性,所以我尝试猜测一下与 linq 并想出了这个:
Expression<Func<ICategorizedEntity, object>> exp = x => x.Category;
var parameter = Expression.Parameter(typeof (T));
var lmd = Expression.Lambda<Func<T, object>>(exp, parameter);
Map(lmd);
这不起作用,因为在“Map”函数的深处,它检查以下内容:
MemberExpression memberExpression = (MemberExpression) null;
if (expression.NodeType == ExpressionType.Convert)
memberExpression = ((UnaryExpression) expression).Operand as MemberExpression;
else if (expression.NodeType == ExpressionType.MemberAccess)
memberExpression = expression as MemberExpression;
if (enforceCheck && memberExpression == null)
throw new ArgumentException("Not a member access", "expression");
我得到“不是成员访问\r\n参数”名称:表达式”。
我如何创建和转换 MemberExpression 或任何类似的可以工作的东西?
I'm trying to creating a dynamic base mapping with fluent nhibernate.
What I'm doing is checking in by a BaseMap< T > : ClassMap< T > if for example:
(typeof(ICategorizedEntity).IsAssignableFrom(typeof(T)))
If so, I wanna map a property named "Category" which belongs to ICategorizedEntity's interface, but the Map(Func) function only accepts T's properties, so I tried guessing a little with linq and came up with this:
Expression<Func<ICategorizedEntity, object>> exp = x => x.Category;
var parameter = Expression.Parameter(typeof (T));
var lmd = Expression.Lambda<Func<T, object>>(exp, parameter);
Map(lmd);
Which doesn't work, because deep inside the 'Map' function it checks the following:
MemberExpression memberExpression = (MemberExpression) null;
if (expression.NodeType == ExpressionType.Convert)
memberExpression = ((UnaryExpression) expression).Operand as MemberExpression;
else if (expression.NodeType == ExpressionType.MemberAccess)
memberExpression = expression as MemberExpression;
if (enforceCheck && memberExpression == null)
throw new ArgumentException("Not a member access", "expression");
And I get the "Not a member access\r\nParameter name: expression".
How can I create and cast a MemberExpression or anything similar which will work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Func
表示接受DerivedFromT
参数的方法。Func
表示接受T
参数的方法。通过 C# 4 中引入的 委托变体,您可以强制转换Func< ;T,object>
到Func
,但不是相反(如您所请求)。想想这意味着什么:
在本例中,
Greet
方法与委托Func
匹配,而Promote
方法与委托Func匹配委托
Func
。我们可以将
Greet
转换为Func
;如果我们可以问候一个Person
,那么我们也可以问候一个Student
(他保证是Person
的一种特殊形式)。但是,我们无法将
Promote
转换为Func
;尽管我们可以晋升学生
,但我们一般不能晋升任何人
,除非他/她恰好是学生
。如果我们知道我们的
Person
是一名学生,我们可以通过强制转换来表明这一点:Func<DerivedFromT,object>
represents a method that accepts aDerivedFromT
parameter.Func<T,object>
represents a method that accepts aT
parameter. Through delegate variance introduced in C# 4, you can castFunc<T,object>
toFunc<DerivedFromT,object>
, but not the other way round (as you’re requesting).Think about what this means:
In this case, the
Greet
method matches the delegateFunc<Person,object>
, whilst thePromote
method matches the delegateFunc<Student,object>
.We can cast
Greet
toFunc<Student,object>
; if we can greet aPerson
, then we can also greet aStudent
(who is guaranteed to be a specialized form ofPerson
).However, we cannot cast
Promote
toFunc<Person,object>
; although we can promote aStudent
, we cannot promote anyPerson
in general, unless he/she happens to be aStudent
.If we know that our
Person
is a student, we can indicate this by casting it:谢谢道格拉斯,你引导我找到了正确(简单)的答案。
我为了找到它走得太远了。
良好的旧转换(在 lambda 表达式内)成功了:
Thanks Douglas, you lead me to the right (simple) answer.
I went too far trying to find it..
Good old conversion (inside the lambda expression) did the trick: