可以为抽象类的子类创建静态构造函数吗?
Posted
技术标签:
【中文标题】可以为抽象类的子类创建静态构造函数吗?【英文标题】:Can a static constructor be made for the child of an abstract class? 【发布时间】:2016-07-01 18:14:38 【问题描述】:我对 async/await 完全陌生,并且一直在“改进”我两年前编写的一个完全同步的应用程序。我有以下情况,我对我的解决方案不满意。
XAML 绑定到以下两个类:
XAML
private InsuranceEditor _primaryinsurance;
public InsuranceEditor PrimaryInsurance
get return _primaryinsurance;
set if (_primaryinsurance == value) return; _primaryinsurance = value; OnPropertyChanged("PrimaryInsurance");
private InsuranceEditor _secondaryinsurance;
public InsuranceEditor SecondaryInsurance
get return _secondaryinsurance;
set if (_secondaryinsurance == value) return; _secondaryinsurance = value; OnPropertyChanged("SecondaryInsurance");
PrimaryInsurance 和 SecondaryInsurance 类继承自抽象类 Insurance:
abstract class InsuranceEditor : SimpleViewModelBase, ISave, IDataErrorInfo
.................
// Constructor
public InsuranceEditor(PatientDemographicsEditor patient, Billing service)
...
用于异步构造 PrimaryInsurance 的工厂模式 (Async OOP Constructor)
private async Task<PrimaryInsurance> InitializeAsync()
// asyncData = await GetDataAsync();
return this;
public static Task<PrimaryInsurance> Create(PatientDemographicsEditor patient, Billing service)
var ret = new PrimaryInsurance(patient, service);
return ret.InitializeAsync();
// Constructor
private PrimaryInsurance(PatientDemographicsEditor patient, Billing service)
: base(patient, service)
Editor_Id = 1;
........
class SecondaryInsurance : InsuranceEditor
// Constructor
private SecondaryInsurance(PatientDemographicsEditor patient, Billing service)
: base(patient, service)
Editor_Id = 2;
............................
从逻辑上讲,主要和次要保险仅在Editor_Id
上有所不同,因此从共同的InsuranceEditor
继承似乎很自然。现在的问题是“正确地”将 async/await 应用于主要和次要保险。我希望用法类似于:
PrimaryInsurance = await PrimaryInsurance.Create(....)
其中Create(...)
被识别为PrimaryInsurance
的静态方法(不一定是抽象类InsuranceEditor
的静态方法。)
这个可以吗?
编辑#1。发布这个问题后,我想它可能已经被问过了,@ 987654322@ 并且我想要的东西不能在 C# 中完成。这是正确的吗?
编辑 #2:我在 VS 中遇到的问题来自使用说明:
PrimaryInsurance = 等待 PrimaryInsurance.Create(Patient, BILLING);
VS 告诉我:
成员 'InsuranceEditor.Create(PatientDemographicsEditor, Billing)' 无法通过实例引用访问;用类型限定它 改名
然后,如果我允许 VS 创建 Create(...)(这样就不会出现错误),它会在抽象的 InsuranceEditor 类中进行,而不是在 PrimaryInsurance 类中。
internal Task<InsuranceEditor> Create(PatientDemographicsEditor patient, Billing bILLING)
throw new NotImplementedException();
我做错了什么?
【问题讨论】:
如果它们的区别只是Editor_Id
,为什么不只使用一个类并将Editor_Id 作为参数传递给私有构造函数呢?然后你就做await InsuranceEditor.CreatePrimary(...)
或await InsuranceEditor.CreateSecondary(...)
@ScottChamberlain 这正是我写完问题后的想法。但我可以看到其他情况会更困难,所以我希望有一些关于如何在这种情况下通过子类上的静态 Create 使用继承的想法。
我不太确定你的问题是什么。您问“可以完成”,但看起来您的问题中有一个可行的示例。你的问题到底是什么?
必须始终在声明它们的类型上调用静态成员,而不是子类型。所以如果你想打电话给BaseClass.Create()
而不仅仅是Create()
。使用实例方法,您可以在子类中调用 Create()
,因为它也是 BaseClass
的实例,因此它具有相同的公共和受保护实例成员可用,但静态成员绑定到类型(想想 @ 987654340@ object kinda) 不是那种类型的实例。
@JamesFaix: “静态成员必须始终在声明它们的类型上调用,而不是子类型”——这不是真的。例如。给定class A public static void M()
和class B : A
,您可以致电B.M();
。在A
中声明的M()
方法绝对是B
的有效static 成员,可以这样引用。
【参考方案1】:
您仍然没有提供可靠地重现问题的良好Minimal, Complete, and Verifiable code example。但根据示例程序语句和您引用的错误消息,您似乎正试图在与属性名称不明确的上下文中使用 PrimaryInsurance
标识符。
如果你想保留属性的名称,那么在任何你想使用类型名称的地方,你都需要完全限定它。例如:
PrimaryInsurance = await MyNamespace.PrimaryInsurance.Create(Patient, BILLING);
其中MyNamespace
是该类型的实际命名空间。
如果命名空间特别长,或者出于任何其他原因您不想每次都输入整个内容,您可以使用using
指令为类型名称起别名。例如:
using PrimaryInsuranceType = MyNamespace.PrimaryInsurance;
那么你的程序语句可能如下所示:
PrimaryInsurance = await PrimaryInsuranceType.Create(Patient, BILLING);
当然,PrimaryInsuranceType
只是一个例子。你可以使用任何你想要的类型别名,只要它不同于属性名本身(或类中的任何其他属性名)。
【讨论】:
谢谢。做到了。 我已经读了大约一百遍了。我显然没有得到它(因为我认为我在这个问题上这样做了)。几个“Minimal....”的好例子会很有帮助。 @Alan:我不确定如何比minimal reproducible example 和How to Ask 页面更好地解释它。我可以告诉您您的问题如何未能达到标准:不可能简单地复制/粘贴您发布的代码,并且在不对其进行任何更改的情况下尝试编译代码以重现您报告的问题。确保您阅读了How to Ask 页面末尾的链接中的文章。阅读sscce.org 也可以获得奖励积分(这是另一种资源,可帮助人们理解在提问时提供良好代码示例的关键需求)。 非常感谢您的批评——我还在学习中。 (如果有更多的评论者效仿你的例子,那就太好了!)谢谢(指向 sscce.org 的链接以及我出错的地方是最有帮助的)。以上是关于可以为抽象类的子类创建静态构造函数吗?的主要内容,如果未能解决你的问题,请参考以下文章
请教一下C#中父类静态构造函数在子类中为啥不会和子类的静态构造函数一起执行