表达式树-Action<;T>;在C#和VB.NET中
本文关键字:VB NET -Action lt 表达式 gt | 更新日期: 2023-09-27 18:03:38
给定一段简单的代码,它可以在VB.NET:中返回属性的名称
Function NameForProperty(Of T)(ByVal field As Expression(Of Action(Of T))) As String
Dim expression = DirectCast(field.Body, MemberExpression)
Return expression.Member.Name
End Function
它是这样工作的:
NameForProperty(Of String)(Function (s) s.Length) ' ==> returns "Length"
我认为在C#中应该是等价的:
string NameForProperty<T>(Expression<Action<T>> field)
{
var expression = (MemberExpression)field.Body;
return expression.Member.Name;
}
当我尝试调用C#版本时:
NameForProperty<string>(s=>s.Length);
它返回一个编译器错误:
仅分配、调用、递增、递减和新对象表达式可以用作语句
我的问题是:这两段代码之间有什么区别?
编辑
Ivan提供了一个关于为什么代码在C#中不起作用的答案。我仍然很好奇为什么它能在VB.NET.中工作
编辑#2
需要明确的是,我并不是在寻找有效的代码——这只是为什么这些代码可以在VB.NET而不是C#中工作。
public static class TypeMember<TClass>
{
public static string PropertyName<TProp>(Expression<Func<TClass, TProp>> expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
throw new ArgumentException("'expression' should be a property expression");
return body.Member.Name;
}
}
var propName = TypeMember<string>.PropertyName(s => s.Length);
您的版本的问题在于您正在尝试使用Action<T>
。它不返回任何内容,因此lambda的主体(s.Length
(应该是一个语句。事实上,这并不是一个声明。所以编译器抱怨它。
如果你写了,它也会以同样的方式抱怨
public void A()
{
string s = "abc";
s.Length;
}
这是一样的事情。
我不是VB.NET的专家,所以我不能解释为什么它在VB中工作,对不起。
我会尝试将方法更改为Func
而不是Action
。
正如错误所说,你的陈述是无效的。如果您将Action更改为Func,这是可以的,因为Length
是返回值。也许VB编译器还有其他检查/要求。