我一直在使用默认接口实现。认为您必须将接口类型转换为向下格式才能使用默认方法实现。我还找到了关于另一种语法的大量注释,我找不到是否已经包含了该注释,但确实找到了有关其外观的“决定”,但是它不起作用。我做错了吗?还是还不包括这种新语法?
有些相关,但没有回答我的问题: Calling C# interface default method from implementing struct without boxing
关于base<>/base()
语法的说明:https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-11-14.md#default-interface-implementations
关于该提案的Microsoft页面:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods
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));
}
}