下面的代码给出了一个错误:
当创建表达式e但没有为类型'ConsoleApplication1.IKeyed`1 [TKey]'定义属性'Int32 Key'但是很好当func f被创建时,任何人都可以解释为什么以及是否有办法解决它?
Module Module1
Sub Main()
Dim g = New keyedThingGetter(Of KeyedThing, Integer)
Dim thing = g.getThing()
End Sub
End Module
Public Class keyedThingGetter(Of Tthing As IKeyed(Of TKey), TKey)
Public Function getThing() As Tthing
Dim f As Func(Of Tthing, Boolean)
f = Function(thing) thing.Key.Equals(1)
Dim e As Expressions.Expression(Of Func(Of Tthing, Boolean))
e = Function(thing) thing.Key.Equals(1)
Return Nothing
End Function
End Class
Public Interface IKeyed(Of TKey)
ReadOnly Property Key() As TKey
End Interface
Public Class KeyedThing
Implements IKeyed(Of Integer)
Public ReadOnly Property Key() As Integer Implements IKeyed(Of Integer).Key
Get
Return 1
End Get
End Property
End Class
答案 0 :(得分:1)
解决方法位于底部
这很奇怪。我仍然在研究它,但这个“大部分相当”的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))