解决方法在底部
这很奇怪。我仍在研究它,但这个“大部分等效”的 C# 工作正常:
using System;
using System.Linq.Expressions;
interface IKeyed<TKey>
{
TKey Key { get; }
}
class KeyedThing : IKeyed<int>
{
public int Key { get { return 1; } }
}
class KeyedThingGetter<TThing, TKey> where TThing : IKeyed<TKey>
{
public void GetThing()
{
Func<TThing, bool> f = thing => thing.Key.Equals(1);
Expression<Func<TThing, bool>> e = thing => thing.Key.Equals(1);
}
}
class Test
{
static void Main()
{
var g = new KeyedThingGetter<KeyedThing, int>();
g.GetThing();
}
}
编辑:创建的表达式树之间有一个有趣的区别。这是VB表达式(使用Reflector反编译为C#):
Expression<Func<Tthing, bool>> expression = Expression
.Lambda<Func<Tthing, bool>> (Expression.Call(Expression.Convert
(Expression.Property(Expression.Convert(expression2 =
Expression.Parameter(typeof(Tthing), "thing"), typeof(IKeyed<>)),
(MethodInfo) methodof(IKeyed<TKey>.get_Key, IKeyed<TKey>)), typeof(object)),
(MethodInfo) methodof(object.Equals), new Expression[] {
Expression.Convert(Expression.Constant(1, typeof(int)), typeof(object)) }), new
ParameterExpression[] { expression2 });
这是 C# 版本:
Expression<Func<TThing, bool>> expression = Expression
.Lambda<Func<TThing, bool>> (Expression.Call(Expression.Convert
(Expression.Property(Expression.Convert(expression2 =
Expression.Parameter(typeof(TThing), "thing"), typeof(IKeyed<TKey>)),
(MethodInfo) methodof(IKeyed<TKey>.get_Key, IKeyed<TKey>)), typeof(object)),
(MethodInfo) methodof(object.Equals), new Expression[] {
Expression.Convert(Expression.Constant(1, typeof(int)), typeof(object)) }), new
ParameterExpression[] { expression2 });
区别在于第四行——参数的类型。在 C# 中为typeof(IKeyed<TKey>),而在 VB 中为typeof(IKeyed<>)。
可能是 VB 编译器中的错误?尚未确定。希望 Marc G 能尽快加入,作为常驻表达式树专家...
编辑:鉴于差异,我想出了如何解决它。将其更改为:
Dim e as Expressions.Expression(Of Func(Of Tthing, Boolean))
e = Function(thing as IKeyed(Of TKey)) thing.Key.Equals(1))
或
Dim e as Expressions.Expression(Of Func(Of IKeyed(Of TKey), Boolean))
e = Function(thing) thing.Key.Equals(1))