开发者

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

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#.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜