表达式<;Func<;对象>>;作为流畅界面的一部分
本文关键字:gt lt 界面 一部分 Func 对象 表达式 | 更新日期: 2023-09-27 17:58:15
考虑这样的接口:
new Provider().For(myClass).ExcludeProperties("Height", "Width");
public IEditableStateProvider For(object target) {...}
public IEditableStateProvider ExcludePropertyNames(params string[] propertyNames) {...}
我想用params Expression<Func<object>>[] propertyNames
替换params string[] propertyNames
参数,这样我就可以得到以下内容。
new Provider().For(myClass).ExcludeProperties(()=>Height, ()=>Width);
我见过类似的代码,所以我认为应该工作,但我还没有得到它。我怎样才能让它发挥作用?
编辑-在没有Generics的情况下执行此操作
以下是一些来自开源项目的代码,我正在研究在没有任何泛型的情况下进行类型推理的情况。我也在想做同样的事情,但我不知道类型推断是从哪里来的(我做看到它在工作!)
// USAGE (here this is being called from code-behind of a WPF window
private void TrackSelectedTab() {
Services.Tracker.Configure(tabControl)
.AddProperties(() => tabControl.SelectedIndex);
Services.Tracker.ApplyState(tabControl);
}
private void TrackMainWindow() {
Services.Tracker.Configure(this)
.AddProperties(
() => Height,
() => Width,
() => Left,
() => Top,
() => WindowState)
.SetKey("MainWindow")
.SetMode(PersistModes.Automatic);
Services.Tracker.ApplyState(this);
}
// Collab classes
public class SettingsTracker
{
public TrackingConfiguration Configure(object target) {
...
return config;
}
}
public class TrackingConfiguration
{
public TrackingConfiguration AddProperties(params Expression<Func<object>>[] properties) {
...
return this;
}
}
static class Services
{
public static readonly SettingsTracker Tracker = new SettingsTracker(ObjectStore);
}
您应该在非泛型类的基础上创建一个泛型Provider
类,这样您就可以利用类型推理和类型安全:
接口:
interface IEditableStateProvider<T>
{
IEditableStateProvider<T> For(T target);
IEditableStateProvider<T> ExcludePropertyNames(params Expression<Func<T, object>>[] excludedProperties);
}
虚拟实现:
class Provider<T> : IEditableStateProvider<T>
{
public IEditableStateProvider<T> For(T target)
{
// dummy
return this;
}
public IEditableStateProvider<T> ExcludePropertyNames(params Expression<Func<T, object>>[] excludedProperties)
{
// dummy
return this;
}
}
class Provider
{
// generic factory method to make use of type inference
public static IEditableStateProvider<T> For<T>(T obj)
{
return new Provider<T>().For(obj);
}
}
用法:
var myClass = new List<object>(); // or whatever
Provider.For(myClass).ExcludePropertyNames(x => x.Count);
现在,当您调用.For(myClass)
时,类型T
是推断出来的,现在您可以在调用ExcludePropertyNames
时通过lambda以类型安全的方式访问类型T
的属性。
如果你真的想要一个非通用版本:
interface IEditableStateProvider
{
IEditableStateProvider For(object target);
IEditableStateProvider ExcludePropertyNames(params Expression<Func<object>>[] excludedProperties);
}
class Provider : IEditableStateProvider
{
public IEditableStateProvider For(object target)
{
// dummy
return this;
}
public IEditableStateProvider ExcludePropertyNames(params Expression<Func<object>>[] excludedProperties)
{
// dummy
return this;
}
}
var myClass = new List<object>();
new Provider().For(myClass).ExcludePropertyNames(() => myClass.Count);
但请注意我在下面的评论。