0

考虑这样的接口:

new Provider().For(myClass).ExcludeProperties("Height", "Width");

public IEditableStateProvider For(object target) {...}
public IEditableStateProvider ExcludePropertyNames(params string[] propertyNames) {...}

我想将params string[] propertyNamesarg替换为,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);
}
4

1 回答 1

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),并且您现在可以T在调用时通过 lambda 以类型安全的方式访问类型的属性ExcludePropertyNames


如果你真的想要一个非通用版本:

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);

但请注意我在下面的评论。

于 2013-02-08T13:35:10.663 回答