鉴于以下示例,是否可以使用() => 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
答案 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参数名称,那么实际上并不存在。