1

最初に、私が達成しようとしていることを説明します。

ロギング目的でプロパティ名とその値を取得するメソッドを作成したいので、次のようにします。

public void Log<TPropertySource, TProperty>(Expression<Func<TPropertySource, object>> property, TProperty initialValue, TProperty changedValue){...}

ここで、プロパティのタイプを指定する必要があります。これは .. meh です。理論的には式からそれを引き出すことができるからです。ただし、式は、プロパティが持つことができるすべての可能な型に対応するオブジェクトを返す必要があります。

私は、BCL で最もよく使用される値型のオーバーロードと、それ以外のオブジェクトのオーバーロードを考えています。

public void Log<TPropertySource>(Expression<Func<TPropertySource, string>> property, string initialValue, string changedValue){...}

public void Log<TPropertySource>(Expression<Func<TPropertySource, int>> property, int initialValue, int changedValue){...}

しかし、それも理想的ではありません。

だから基本的に、それを行うためのより良い(怠惰な)方法があるのだろうか?

もう 1 つの質問: Log<TPropertySource>(Expression<Func<TPropertySource, int>> property, int initialValue, int changedValue) でインテリセンスが得られないのはなぜ ですか? logger.Log <A>(x => x.Age, 1, 2); と入力すると、- 正常にコンパイルされますが、インテリセンスは起動しません。

4

1 に答える 1

0

最も簡単な方法は、ラムダ式でプロパティ ソース タイプを指定することlogger.Log((User _) => _.Age, 1, 2)です。そのため、すべてのタイプが推測されます。

もう 1 つの方法は、型パラメーターを分離して、1 つずつ推論または指定できるようにすることです。一般的なパターンは次のとおりです。

n 型パラメータを持つメソッド M があるとします。


class C
{
    public void M<T1, T2, ..., Tn>(...) {}
}

それらのすべてを推測するか、すべてを明示的に指定する必要があります。それらを個別に指定/推測するには、API を変更して、すべての型パラメーターの中間メソッドと型を提供する必要があります。


class C
{
    public T1Binder<T1> M1<T1>(...) {}
}

class T1Binder<T1>
{
    public T2Binder<T2> M2<T2>(...) {}
}

...

class TFinalBinder<T(n - 1)>
{
    public void MFinal<Tn>(...) {}
}

これで、すべての型パラメーターを個別に推論または指定できる一連の呼び出しを作成できます。


c.M1<T1>().M2(t2Value)...MFinal(tnValue);

あなたの場合、次のようになります。


public class Logger
{
    public PropertyLogger<TPropertySource> PropertyOf<TPropertySource>()
    {
        return new PropertyLogger<TPropertySource>();
    }
}

public class PropertyLogger<TPropertySource>
{
    public void Log<TProperty>(
        Expression<Func<TPropertySource, object>> property,
        TProperty initialValue,
        TProperty changedValue)
    {
    }
}

これは、たとえばで使用できますlogger.PropertyOf<SomeType>().Log(_ => _.Age, 1, 2)。この API の実装と使用は明らかに複雑ですが、複数のプロパティを処理する必要がある場合に便利です。


logger.PropertyOf<SomeType>()
    .Log(_ => _.Age, 1, 2)
    .Log(_ => _.Name, "Mike", "Adam");

また、API ユーザーが特定のケースに適した方を選択できるように、両方のアプローチを組み合わせることができます。

于 2013-09-20T07:58:41.833 に答える