代码之家  ›  专栏  ›  技术社区  ›  Zev Spitz

参数的可空性与约束类型不匹配

  •  0
  • Zev Spitz  · 技术社区  · 4 年前

    public static void NotifyChanged<T>(this INotifyPropertyChanged inpc, ref T current, T newValue, Action<PropertyChangedEventArgs> eventRaiser, [CallerMemberName] string? name = null) where T : IEquatable<T> {
        if (current.Equals(newValue)) { return; }
        current = newValue;
        eventRaiser(new PropertyChangedEventArgs(name));
    }
    

    可以这样使用:

    public class Foo : Bar, INotifyPropertyChanged {
        public event PropertyChangedEventHandler? PropertyChanged;
    
        private string? rootExpression;
    
        public string? RootExpression {
            get => rootExpression;
            set => this.NotifyChanged(ref rootExpression, value, args => PropertyChanged?.Invoke(this, args));
        }
    }
    

    这节省了编写INPC感知属性的大量样板文件。

    但是,现在在调用 NotifyChanged :

    类型“string?”不能用作泛型类型或方法“INotifyPropertyChangedExtensions.NotifyChanged(INotifyPropertyChanged,ref T,T,Action,string?)中的类型参数“T”。类型参数“string”的可空性与约束类型“System.IEquatable”不匹配。

    但错误是这样说的 string? 无法强制转换为 IEquatable<string?> ,仅 string 可以转换为 IEquatable<string> .

    我该怎么解决?应用某些属性?或者别的什么?

    1 回复  |  直到 4 年前
        1
  •  3
  •   canton7    4 年前

    你的问题是:

    where T : IEquatable<T>
    

    上面写着 T IEquatable<T> . 你希望它可以为空。你可以通过添加 ? :

    where T : IEquatable<T>?
    

    注意,这将抱怨 if (current.Equals(newValue)) ,如果 current null


    通常的方法不是通过约束 成为一个 可量化<T> ,但要使用 EqualityComparer<T>.Default T型 工具 可量化<T> IEquatable<T>.Equals ,否则返回到调用 object.Equals .

    这也解决了您的NRE问题,如果 无效的 :

    public static void NotifyChanged<T>(
        this INotifyPropertyChanged inpc,
        ref T current, T newValue,
        Action<PropertyChangedEventArgs> eventRaiser,
        [CallerMemberName] string? name = null)
    {
        if (EqualityComparer<T>.Default.Equals(current, newValue)) { return; }
        current = newValue;
        eventRaiser(new PropertyChangedEventArgs(name));
    }
    

    eventRaiser :通常你会 NotifyChanged 基类上实现 INotifyPropertyChanged ,而不是使其成为扩展方法。然后你就可以 提高 PropertyChanged OnPropertyChanged 使 财产变更 打电话给 通知已更改 .

    PropertyChangedEventHandler :

    public static void NotifyChanged<T>(
        this INotifyPropertyChanged _,
        ref T current, T newValue,
        PropertyChangedEventHandler eventHandler,
        [CallerMemberName] string? name = null)
    {
        if (EqualityComparer<T>.Default.Equals(current, newValue)) { return; }
        current = newValue;
        eventHandler?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    
    this.NotifyChanged(ref rootExpression, value, PropertyChanged);
    
    推荐文章