0

INotifyPropertyChanged の厳密に型指定された実装を実装しましたが、インターフェイスを使用する代わりに、実装する基本クラスを追加しました。

それは正常に動作しますが、私が苦労しているのは、ベースメソッドの宣言で TValue が使用されている理由です (オンラインで見つけたコードからこのセクションを使用しました)。

NotifyPropertyUpdate<TValue>(...

しかし、派生クラスでは、渡す必要はまったくありませんTValue!

ビルド時に不平を言うのではなく、実行時にこれを解決するようにコンパイラに指示するものは何ですか?

ありがとう、

基本クラス:

public class NotifyFuncPropertyChanged<T> : INotifyPropertyChanged
{
    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyUpdate<TValue>(Expression<Func<T, TValue>> selector)
    {
        //get memberInfo from object selection
        MemberInfo memberInfoSelection;
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.MemberAccess:
                memberInfoSelection =((MemberExpression)body).Member;
                break;
            default:
                throw new InvalidOperationException();
        }

        //send notifyupdate to memberInfo
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(memberInfoSelection.Name));
        }
    }

    #endregion
}

使い方(派生クラス)

public class NameTest : NotifyFuncPropertyChanged<NameTest>
{
    public string Name { get; set; }

    public void TestUpdateName()
    {
        this.NotifyPropertyUpdate(x => x.Name);
    }
}
4

3 に答える 3

3

C#コンパイラには、型推論と呼ばれる機能があります。言語仕様のすべての複雑さについては、セクション7.5.2で読むことができます。または、ここに非常に簡単な紹介があります。

仕様から:

型引数を指定せずにジェネリックメソッドが呼び出されると、 型推論プロセスはその呼び出しの型引数を推論しようとします。型推論の存在により、ジェネリックメソッドを呼び出すために、より便利な構文を使用できるようになり、プログラマーは冗長な型情報を指定することを回避できます。たとえば、メソッド宣言が与えられた場合:

class Chooser
{
  static Random rand = new Random();
  public static T Choose<T>(T first, T second) {
      return (rand.Next(2) == 0)? first: second;
  }
}

Chooseタイプ引数を明示的に指定せずにメソッドを呼び出すことができます。

int i = Chooser.Choose(5, 213);                   // Calls Choose<int>
string s = Chooser.Choose("foo", "bar");      // Calls Choose<string>

型推論により、型引数intstringはメソッドへの引数から決定されます。

于 2012-08-30T12:58:50.023 に答える
2

TValueコンパイラは、引数から自動的に推測できます。実際には、呼び出し行は次のようにコンパイルされます。

this.NotifyPropertyUpdate<string>(x => x.Name);

ほとんどすべての LINQ 拡張メソッドを呼び出すと、これと同じことが起こっていることがわかります。

于 2012-08-30T11:30:50.463 に答える
1

コンパイラは の型を推測しTValueます。実行時ではなく、コンパイル時に発生します。

次のラムダを渡します: x => x.Name. コンパイラNameは、 が型stringであることを認識しているため、TValueですstring

于 2012-08-30T11:29:02.050 に答える