是否可以为单个属性选择器指定表达式?

时间:2015-04-01 19:50:52

标签: c# lambda expression

我可以指定一个方法将Expression<Func<Foo, object>>作为参数,以获得看起来像这样的api:

// With a method declaration like this...
public void Foo(Expression<Func<Bar, object>> selector) { .... }

// ...I can invoke the method like this
Foo(b => b.Baz);
Foo(b => new { b.Baz, b.Foo });

但是,我正在编写一个API,这样可以允许选择单个属性。像这样:

public void Foo(Expression<Func<Bar, ...>> selector) { .... }

// This would be OK.
Foo(b => b.Baz);

// But this would not...
Foo(b => new { b.Baz, b.Foo });

有没有办法表达这种方式以这种方式限制表达式?

当然,我总是可以记录这个并在运行时检查表达式,但如果可能的话,我宁愿制作一个不会抛出RuntimeExceptions的API,如果我可以避免它。

编辑:

我想我可以将方法声明中Func的返回值更改为特定类型,从而至少限制表达式。但是我不想这样做,因为我希望在这个方法调用中能够接受几乎任何类型的属性。

2 个答案:

答案 0 :(得分:2)

不,没有办法通过静态检查要求表达式只是表达式属性的属性访问。您只能在运行时执行此类检查。

答案 1 :(得分:0)

如果您将特定父对象用于可接受的类型,则以下内容将在编译时强制执行参数

public void Foo<TSource, TTarget>(Expression<Func<TSource, TTarget>> selector)
    where TSource : Bar
    where TTarget : Bar
{ ... }

由于匿名类型派生自object,因此TSourceTTarget必须派生自Bar

,这会阻止其使用

但是,这仅指定源和结果是从特定类型派生的 - 根据定义,运行时检查检查表达式是什么,因为您正在验证对象中的数据。