【问题标题】:C#: AmbiguousMatchException: ambiguous match foundC#:AmbiguousMatchException:找到不明确的匹配项
【发布时间】:2017-06-30 12:15:42
【问题描述】:

我得到了例外:

AmbiguousMatchException:找到不明确的匹配项

当打开我的窗口并解析 XAML 时。我有一个基本的 ViewModel 类。它具有 DataGrid 的 SelectedItem 属性的属性

public class BaseViewModel<T> : ViewModel, INotifyPropertyChanged where T : MyClass
{
    protected T _selectedItem;
    public T SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            _selectedItem = value;
            OnPropertyChanged();
        }
    }
}

在我继承的 ViewModel 中,我覆盖了产生异常的属性

public new MyInheritedClass SelectedItem
{
    get
    {
        return _selectedItem;
    }
    set
    {
        _selectedItem = value;
        OnPropertyChanged();
        //Do other stuff
    }
}

那么如何使用被覆盖的属性而不出现异常呢?

【问题讨论】:

    标签: c# wpf xaml oop mvvm


    【解决方案1】:

    为什么要重新定义派生类中的属性?派生类的类型参数应该指定属性的类型:

    public class MyInheritedClass : BaseViewModel<MyClass>
    {
        //no need to define a new SelectedItem property...
    }
    

    在上面的示例代码MyInheritedClass 中已经有一个SelectedItem 类型为MyClass 的属性。它已经在基类中定义。你不需要创建一个新的。

    如果属性需要在派生类中做一些特殊的事情,你应该在基类中将属性定义为virtual

    public virtual T SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            _selectedItem = value;
            OnPropertyChanged();
        }
    }
    

    ...并在派生类中覆盖它:

    public override MyClass SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            _selectedItem = value;
            OnPropertyChanged();
            //Do other stuff
        }
    }
    

    【讨论】:

    • 因为我需要为继承的类做一些特别的事情。查看新属性中的评论
    • 那么你应该在基类中使属性为虚拟,并在派生类中覆盖它。请参阅我编辑的答案。
    【解决方案2】:

    如果您定义了一个已经存在于基类中的属性(或依赖属性的访问器),就会发生这种情况。因为那样你就会变得模棱两可。您必须覆盖(主题:虚拟)或新建(隐藏)它。否则 WPF 中发生的反射将处理歧义。

    例子:

    public partial class My : UserControl
    {
    // this will make the ambiguity with the existing trigges-DP legacy accessor
    public int Triggers {get;set;}
    
    // this will not make ambiguities, because it hides the original.
    // however it may cause other problems
    public new object Background {get;set; }
    
    // also OK, but needs justification as well.
    public override object ExistingVirtualProperty {get;set; }
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多