Jul*_*ian 0 c# abstract-class partial-classes sourcegenerators
我有一个继承自抽象类的基类,但它本身必须声明为partial,因为我正在使用源生成器来生成部分实现。
如何防止partial class在 C# 中实例化它?有没有办法在编译时做到这一点?
编辑:我将 C# 8.0 (.NET Standard 2.1) 与 Xamarin.Forms 项目一起使用。
我试过了partial abstract,但是这是不允许的。
在我的一个项目中,我一直使用一个abstract class作为ViewModel 的基类来实现MVVM 模式。以前,所述基类实现了该INotifyPropertyChanged接口,但现在我切换到CommunityToolkit.Mvvm,以便能够使用MVVM 源生成器 (我已经在其他项目中广泛使用了它,我什至写了一个关于它们的博客系列) 。
显然,在 C# 中,一个类只能是其中之一partial,abstract但不能同时是两者,这是有道理的。由于源生成器仅与类一起使用partial,因此我的基类不能abstract再这样了。但是,这会产生一个问题,即我无法阻止基类在编译时实例化。虽然它仍然是一个abstract class,但无法实例化,但现在可以这样做。
这就是基类过去的样子(简化/修改的示例):
public abstract class ViewModelBase : INotifyPropertyChanged
{
private bool _myBool;
public bool MyBool
{
get => _myBool;
set => SetField(ref _myBool, value);
}
private ICommand _myCommand;
public ICommand MyCommand => _myCommand ??= new Command(MyMethod);
private void MyMethod()
{
// ...
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
更改后的基类现在如下所示:
public partial class ViewModelBase : ObservableObject
{
[ObservableProperty]
private bool _myBool;
[RelayCommand]
private void MyMethod()
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它要小得多,但现在它可以被实例化,这是我想阻止的事情。
您可以将部分类声明为抽象,但请注意关键字的顺序很重要(否则它将无法编译):
public abstract partial class ViewModelBase : ObservableObject
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
根据规范abstract- 、等修饰符sealed应位于partial关键字之前。