我在尝试使Func<T>
表达式评估对象实例中的属性时遇到了一些困难,例如
var t = new Transition<ILexeme>( 1, () => TokenType == eToken.TOKEN_COMMENT );
Visual Studio编译器抱怨非静态字段,方法或属性'ILexeme.TokenType.get'错误需要对象引用,因为它期望{{1}对象实例。
我尝试做的是创建一个状态机,使用ILexeme
来调用转换函数的委托,该委托测试Func<T>
属性的值是否与eToken
匹配在令牌流中。如果它相等,则机器移动到下一个状态。
问题是我将eToken
作为泛型类型传递给ILexeme
类,但我希望转换函数使用泛型类型中的属性,即Transition
。我的问题是如何实现这一目标
请记住必须适用于值类型,即TokenType
,char
等?
以下是ILexeme的定义:
int
以下是ILexeme的具体实现:
public interface ILexeme
{
eToken TokenType { get; }
String TokenString { get; }
}
这是Transition的定义:
public enum eToken : int
{
TOKEN_COMMENT,
TOKEN_SEPARATOR
}
public class Token : ILexeme
{
public eToken TokenType { get; }
public String TokenString { get; }
}
答案 0 :(得分:2)
在Transition<ILexeme>
- 构造函数中,您希望Func<ILexeme>
,但提供Func<bool>
。
答案 1 :(得分:2)
我认为你已经错误地写了你的lambda表达式。由于TokenType
是一个实例属性,因此您应该将对象的实例传递给lambda。现在它没有参数。所以,我认为它应该像
var t = new Transition<ILexeme>( 1, eTok => eTok.TokenType == eToken.TOKEN_COMMENT );
转型课
public readonly int FromState;
public readonly int ToState;
public readonly Func<T, bool> Input;
public Transition( int fromState, Func<T, bool> input, int toState )
{
this.FromState = fromState;
this.ToState = toState;
this.Input = input;
}
此外,您可能希望将第二个类型参数引入Transition
类,因此它变得非常通用:
class Transition<TInput, TResult> {
public readonly int FromState;
public readonly int ToState;
public readonly Func<T, TResult> Input;
public Transition( int fromState, Func<T, TResult> input, int toState )
{
this.FromState = fromState;
this.ToState = toState;
this.Input = input;
}
}
如果是这种情况,您可能希望使用where clause放置一些类型约束。
答案 2 :(得分:1)
您得到的错误是因为TokenType是ILexeme类型的属性,但在您对构造函数的调用中,没有该类型的有效实例。也许你希望你的宣言是
public Transition(int fromState, Func<T, bool>, int toState) { /* ... */ }
然后你可以编写你的代码:
var t = new Transition<ILexeme>(1, lex => lex.TokenType == eToken.TOKEN_COMMENT, 2);