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)型のプロパティにアクセスできるようになりました。TExcludePropertyNames


非汎用バージョンが本当に必要な場合:

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 に答える