我一直在搞乱默认的接口实现。认为您必须对接口类型进行向下转换才能使用默认方法实现。我还发现了一堆关于另一种语法的注释,我找不到它是否已经包含在内,我确实找到了关于它的外观的“决定”,但是它不起作用。我做错了还是这个新语法还没有包括在内?
有点相关但没有回答我的问题: Calling C# interface default method from implementation struct without boxing
base<>/base()
语法注释: https ://github.com/dotnet/cshaplang/blob/master/meetings/2018/LDM-2018-11-14.md#default-interface-implementations
class D : IA, IB, IC
{
//Notice the use of base() right here.
void IA.M() { base(IB).M(); }
}
所以说我们需要在某个对象上使用 INotifyPropertyChanged。我们现在可以在接口上默认设置一个 SetField 实现:
public interface INotify : INotifyPropertyChanged
{
void InvokePropertyChanged(string propertyName);
bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
INotify thing = (INotify)this;
if (propertyName == null)
{
throw new ArgumentException($"{nameof(propertyName)} is null. PropertyChangedEventHandler will not be fired correctly.");
}
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
InvokePropertyChanged(propertyName);
return true;
}
}
实现它需要一个向下转换(((INotify)this).SetField
),base(INotify)
这里最好使用。
public class Thing : INotify
{
public string A
{
get => _a;
//Need an explicit cast here. Can't figure out how to use base syntax.
set => ((INotify)this).SetField(ref _a, value);
}
private string _a;
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}