考虑这样的界面:
new Provider().For(myClass).ExcludeProperties("Height", "Width");
public IEditableStateProvider For(object target) {...}
public IEditableStateProvider ExcludePropertyNames(params string[] propertyNames) {...}
我想将params string[] propertyNames
arg替换为params Expression<Func<object>>[] propertyNames
,以便我改为拥有以下内容。
new Provider().For(myClass).ExcludeProperties(()=>Height, ()=>Width);
我见过与此类似的代码,所以我认为应该工作,但我还没有得到它。我怎样才能让它发挥作用?
以下是我正在查看的类型推断在没有任何泛型的情况下工作的开源项目的一些代码。我当时也想做同样的事情但是我没有看到类型推断的来源(我做看到它工作了!)
// 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);
}
答案 0 :(得分:3)
您应该创建一个通用的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);
现在,当您调用T
时,类型.For(myClass)
已被激活,您现在可以在调用{{1}时通过lambda以类型安全的方式访问类型T
的属性}。
如果你真的想要非通用版本:
ExcludePropertyNames
但请注意下面的评论。