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. 它仍然发生在编译时,而不是运行时。

您传入以下 lambda: x => x.Name。编译器知道它Name是类型string,因此TValuestring

于 2012-08-30T11:29:02.050 回答