Expression trees - different compiler behaviour for Action<T> in C# and VB.NET

夙愿已清 提交于 2019-12-24 01:03:58

问题


Given a simple piece of code which can return the name of a property in 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

Which works like this:

NameForProperty(Of String)(Function (s) s.Length) ' ==> returns "Length"

And what I thought would have been the equivalent in C#:

string NameForProperty<T>(Expression<Action<T>> field)
{
    var expression = (MemberExpression)field.Body;

    return expression.Member.Name;
}

When I try to call the C# version:

NameForProperty<string>(s=>s.Length);

It returns a compiler error:

Only assignment, call, increment, decrement, and new object expressions can be used as a statement

My question is: what is the difference between the two pieces of code?

EDIT

Ivan has provided an answer as to why the code does not work in C#. I am still curious as to why it does work in VB.NET.

EDIT#2

To be clear, I'm not looking for code which works -- simply why the code would work in VB.NET and not C#.


回答1:


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);

The problem with your version lies in the fact that you're trying to use Action<T>. It returns nothing and thus lambda's body (s.Length) should be a statement. And it is not a statement actually. So compiler complains about it.

It would complain in the same way if you'd wrote

public void A()
{
    string s = "abc";
    s.Length;
}

It is the same thing.

I'm not an expert in VB.NET though, so I can't explain why it is working in VB, sorry.




回答2:


I would try changing the method to Func instead of Action.

Your statement is not valid as the error says. If you change the Action to Func it's ok, because Length is the return value. Maybe the VB compiler has other checks / requirements.



来源:https://stackoverflow.com/questions/6811868/expression-trees-different-compiler-behaviour-for-actiont-in-c-sharp-and-vb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!