带无参数输入的表达式

时间:2014-07-25 21:32:31

标签: c# lambda .net-4.5

鉴于以下示例,是否可以使用() => MyProperty语法推断MyClass

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace MyNamespace
{
    class Program
    {
        private static void Main(string[] args)
        {
            // This compiles fine:
            var map = new Dictionary<Expression<Func<MyClass, object>>, string>
            {
                // Lambda Expression has a single argument of "MyClass".
                {x => x.MyProperty, "Hello world"}
            };

            // Is is possible to initialize Dictionary using parameter-less lambda?
            var map2 = new Dictionary<Expression<Func<??????>>, string>
            {
                // Can the Lambda be parameter-less (infer MyClass automagically)?
                {() => MyProperty, "Hello world"}
            };
        }
    }

    class MyClass
    {
        public string MyProperty { get; set; }
    }
}

代码也在.NET小提琴上:https://dotnetfiddle.net/OVERm3

2 个答案:

答案 0 :(得分:4)

简而言之,没有。 C#没有这样的工作。

首先,令牌SomeProperty在使用Program.Main的上下文中没有意义。没有。 Program类上没有与之匹配的静态属性或字段,并且无论它们有多接近,它都不会在其他类中寻找一个静态属性或字段。这称为Lexical Scope,这很重要。

其次,SomeClass.SomeProperty是一个实例属性,因此您无法在没有实例引用的情况下访问它。即使班级中的方法遵循该规则,如果您不自己指定,语言也会暗示this

最后,LambdaExpression无效,因为无法将其编译为正常运行的代码。 Lambda不是魔术,它们在内部遵循相同的规则,所有其余代码都遵循相同的规则。当然编译器做了一些有趣的事情来实现它们,类型推断非常酷,但一般规则是:如果你不能在其他代码中执行它,你就不能在lambda中完成它。

所以真正的问题是,你究竟想要在这里实现什么?这为你解决了什么问题,以及如何解决?如果我们知道,或许我们可以提供一些替代方案。

答案 1 :(得分:0)

() => MyProperty表示“没有任何内容,请评估为MyProperty”。如果MyProperty是本地属性,那么这可能有意义,但它不等同于x => x.MyProperty,其中“给定x,评估为x.MyProperty

另一种可能性是,x已在其他地方定义。你可以说() => x.MyProperty。这将“捕获”x,但如果你不小心你会遇到问题,并且会增加不必要的复杂性。

基本上,如果您正在寻找一种速记方法来避免两次输入lambda参数名称,那么实际上并不存在。