C# 表达式的arg数组<;Func<;对象>&燃气轮机;作为流畅界面的一部分
考虑这样一个接口:C# 表达式的arg数组<;Func<;对象>&燃气轮机;作为流畅界面的一部分,c#,lambda,expression-trees,fluent-interface,C#,Lambda,Expression Trees,Fluent Interface,考虑这样一个接口: new Provider().For(myClass).ExcludeProperties("Height", "Width"); public IEditableStateProvider For(object target) {...} public IEditableStateProvider ExcludePropertyNames(params string[] propertyNames) {...} 我想用params Expression[]propert
new Provider().For(myClass).ExcludeProperties("Height", "Width");
public IEditableStateProvider For(object target) {...}
public IEditableStateProvider ExcludePropertyNames(params string[] propertyNames) {...}
我想用params Expression[]propertyNames
替换params string[]propertyNames
参数,这样我就可以得到以下内容
new Provider().For(myClass).ExcludeProperties(()=>Height, ()=>Width);
我见过类似的代码,所以我认为它应该可以工作,但我还没有得到它。我怎样才能让它工作
编辑-在没有泛型的情况下执行此操作
下面是我在看的一个开源项目中的一些代码,其中类型推断在没有任何泛型的情况下工作。我也希望这样做,但我不知道类型推断是从哪里来的(不过我确实看到它在工作!)
//用法(这里是从WPF窗口的代码隐藏调用的
私有void TrackSelectedTab(){
Services.Tracker.Configure(tabControl)
.AddProperties(()=>tabControl.SelectedIndex);
Services.Tracker.ApplyState(tabControl);
}
私有void trackmain窗口(){
Services.Tracker.Configure(此)
.AddProperties(
()=>高度,
()=>宽度,
()=>左,
()=>顶部,
()=>WindowsState)
.SetKey(“主窗口”)
.SetMode(PersistModes.Automatic);
Services.Tracker.ApplyState(this);
}
//协作类
公共类设置
{
公共跟踪配置(对象目标){
...
返回配置;
}
}
公共类跟踪配置
{
公共跟踪配置AddProperties(参数表达式[]属性){
...
归还这个;
}
}
静态类服务
{
公共静态只读设置Stracker Tracker=新设置Stracker(ObjectStore);
}
您应该在非泛型类的基础上创建泛型提供程序
类,以便利用类型推断和类型安全:
接口:
interface IEditableStateProvider<T>
{
IEditableStateProvider<T> For(T target);
IEditableStateProvider<T> ExcludePropertyNames(params Expression<Func<T, object>>[] excludedProperties);
}
但是请注意我下面的评论。您应该在非泛型类的基础上创建泛型
提供程序
类,以便利用类型推断和类型安全:
接口:
interface IEditableStateProvider<T>
{
IEditableStateProvider<T> For(T target);
IEditableStateProvider<T> ExcludePropertyNames(params Expression<Func<T, object>>[] excludedProperties);
}
但请注意我下面的评论。我喜欢你的解决方案,但我想用一种非泛型的解决方案,就像我在原始的后期编辑中添加的代码一样。你看到类型推断是从哪里来的吗?谢谢你在编辑中发布的代码根本不使用类型推断。虽然它是非泛型的,但它也不是sa类型fe.没有什么可以阻止您使用它,例如
.Configure(tabControl).AddProperties(()=>12345);
(其中int
12345显然不是tabControl
的属性)。它与高度
、宽度
等一起工作。因为这些属性是可访问的,因为.AddProperties
用于具有这些属性的类(我猜它是表单
)。我强烈建议使用泛型方法,因为它确保您只能使用传递给For
@Berryl的类型/对象的属性。尽管如此,我还是添加了一个非泛型版本。我没有意识到非泛型代码不是类型安全的(老实说,我仍然不确定intellisense如何获取属性!)。谢谢你的帮助,谢谢。我喜欢你的解决方案,但我一直在想一个非泛型的解决方案,这与我在最初的博文编辑中添加的代码是一致的。你看到类型推断是从哪里来的吗?谢谢。你在编辑中发布的代码根本不使用类型推断。虽然它是非泛型的,但它也不是类型安全的。没有ng阻止您使用它,例如.Configure(tabControl).AddProperties(()=>12345);
(其中int
12345显然不是tabControl
的属性)。它与高度
、宽度
等一起工作。因为这些属性是可访问的,因为.AddProperties
用于具有这些属性的类(我猜它是表单
)。我强烈建议使用泛型方法,因为它确保您只能使用传递给For
@Berryl的类型/对象的属性。尽管如此,我还是添加了一个非泛型版本。我没有意识到非泛型代码不是类型安全的(老实说,我仍然不确定intellisense如何获取属性!).谢谢你的帮助,干杯
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);
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);