是否可以为单个 属性 选择器指定一个表达式?
Is it possible to specify an Expression for a single property selector?
我可以指定一个方法将 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 });
有没有一种表达方式来限制这种表达方式?
当然,我总是可以只记录它并在运行时检查表达式,但如果可能的话,我更愿意制作一个 API 如果我能避免它,它不会抛出 RuntimeExceptions。
编辑:
我想我可以将方法声明中 Func 的 return 值更改为特定类型,从而至少对表达式进行一些限制。但我不想这样做,因为我希望能够在此方法调用中接受几乎任何类型的 属性。
不,无法通过静态检查要求表达式只是对表达式的 属性 的 属性 访问。您只能在运行时执行此类检查。
如果您将特定的父对象用于可接受的类型,以下将在编译时强制执行参数
public void Foo<TSource, TTarget>(Expression<Func<TSource, TTarget>> selector)
where TSource : Bar
where TTarget : Bar
{ ... }
由于匿名类型派生自 object
,这将阻止它们的使用,因为 TSource
和 TTarget
都必须派生自 Bar
但是,这仅指定源和结果派生自特定类型 - 根据定义,检查表达式是什么是运行时检查,因为您正在验证对象中的数据。
我可以指定一个方法将 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 });
有没有一种表达方式来限制这种表达方式?
当然,我总是可以只记录它并在运行时检查表达式,但如果可能的话,我更愿意制作一个 API 如果我能避免它,它不会抛出 RuntimeExceptions。
编辑:
我想我可以将方法声明中 Func 的 return 值更改为特定类型,从而至少对表达式进行一些限制。但我不想这样做,因为我希望能够在此方法调用中接受几乎任何类型的 属性。
不,无法通过静态检查要求表达式只是对表达式的 属性 的 属性 访问。您只能在运行时执行此类检查。
如果您将特定的父对象用于可接受的类型,以下将在编译时强制执行参数
public void Foo<TSource, TTarget>(Expression<Func<TSource, TTarget>> selector)
where TSource : Bar
where TTarget : Bar
{ ... }
由于匿名类型派生自 object
,这将阻止它们的使用,因为 TSource
和 TTarget
都必须派生自 Bar
但是,这仅指定源和结果派生自特定类型 - 根据定义,检查表达式是什么是运行时检查,因为您正在验证对象中的数据。