- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个抽象类作为各种实现的基类。
让它看起来像这样:
public abstract class MyBase {
public object Property1 { get; protected set; }
}
重要的是,Property1
的类型是object
而不是object?
。我希望完全清楚 Property1
在实现实例中永远不会为 null。
假设典型的实现如下所示:
public sealed class MyImpl : MyBase {
public MyImpl() {
Property1 = new object();
}
}
当然,在现实世界中,基类中有很多属性,而且它们的类型各不相同,而不仅仅是object
。我可以将这些属性标记为 abstract
,但是我必须在每个实现类中实现它们 - 这意味着更多的样板代码并没有真正的好处,对吧?
好的,但现在我收到一条警告,在退出构造函数之前属性必须具有非空值 - CS8618。当然,我可以为我的基类禁用警告,但是是否有更优雅的方法来指示编译器实现类必须将这些属性设置为非空值而不是禁用警告?
如果我收到的警告不是针对基类的,而是针对未设置这些属性之一的实现的警告,那将是完美的。
正如我已经发现的那样 - 最新的 C# 编译器和 Visual Studio 有很多神奇的特殊属性可以改变可为 null 的警告行为,但我不知道去哪里找。
最佳答案
It is important, that the type of Property1 is object and not object?. I want it to be completely clear that the Property1 is never null in implementation instance.
保证这一点的唯一方法是使用MyBase
中的protected
构造函数,它需要Property1
的值或通过使Property1
成为抽象
属性。
在 .NET 中,当子类被实例化时,首先它的父类(super class)型的构造函数运行完成,然后是下一个子类型的构造函数,依此类推。目前在 .NET 中没有规定父类(super class)型有一个在最派生类型的构造函数运行之后运行的“后构造函数”(我希望有……),所以 MyBase 没有办法
类以向编译器证明 Property1
在构造对象时将处于有效状态。拥有一个 protected set
不是任何一种可证明的保证(至少就编译器而言):它是 OOP 等同于子类说“我小指发誓要在我的 build 者!”并且程序的其余部分必须相信这个口头 promise 。
这就是自 C# 8.0 以来的可空注释如此重要和有用的原因:因为现在我们不再需要仅仅基于信任来操作:我们现在可以让编译器实际验证一个字段/auto-property 实际上被分配给一个非空值,从而防止任何 NullReferenceException
(每个人最喜欢的异常类型!)从一开始就被抛出。
在这种情况下,非抽象
子类是密封
这一事实对编译器来说无关紧要,因为您的MyBase
仍然可以派生分别由一个从不设置 Property1
的行为不当的子类。
Of course in real world there are plenty of properties in the base class and they are of various types, not just
object
. I could mark the properties asabstract
, but then I would have to implement them in each implementing class - that would mean more boilerplate code with no real benefit in that, right?
我明白必须复制+粘贴或手动击键输入重复的成员很烦人,但如果(重新)实现那些抽象
成员在你的代码中表达了一些有意义的东西,那么这样做不是“样板”业务/领域模型。
I get a warning that the properties must have non-null values before exiting constructor - CS8618. Of course I can disable the warning for my base class, but is there a more elegant way to instruct the compiler that the implementing class MUST set those properties to non-null values instead of disabling the warning?
只需使用一个protected
构造函数。这正是他们的目的。
像这样:
public abstract class MyBase
{
protected MyBase(object property1Value)
{
this.Property1 = property1Value ?? throw new ArgumentNullException(nameof(property1Value));
}
public object Property1 { get; }
}
这样所有的子类都是安全的:
public sealed class Derived : MyBase
{
public Derived()
: base( GetProperty1FromAStaticFactory() )
{
}
}
或
public sealed class Derived : MyBase
{
public Derived( Object p1Value )
: base( p1Value )
{
}
}
关于C#如何标记抽象类的属性不为空,因为在实现类构造函数时需要设置(CS8618)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71188860/
这个问题已经有答案了: Is there any way to accept only numeric values in a JTextField? (20 个回答) It's possible i
我使用戴尔 XPS M1710。笔记本电脑的盖子、侧面扬声器和前置扬声器都有灯(3 组灯可以单独调节)和鼠标垫下方的灯。在 BIOS 中,我可以更改这些灯的颜色,至少是每个组。另外,我可以在鼠标垫下打
我知道我可以使用 在 iOS 5 中打开设置应用 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs://"
我有一个 Django 应用程序,我正在尝试为其设置文档。目录结构如下: - doc - project | - manage.py 我已经设置了路径以便 Sphinx 可以看到东西,但是当我尝试使用
我正在使用 768mb ram 运行 centos 5.5。我一直在日志中获取 server reached MaxClients setting, consider raising the MaxC
我在具有以下配置的服务器内运行了 Drupal 安装: StartServers 5 MinSpareServers 5 MaxSpareServers 15 MaxClien
是否可以使用 Microsoft.Web.Administration 包为给定的 location 配置 asp 设置? 我想以编程方式将以下部分添加到本地 IIS applicationHost.
我一直在阅读为 kube-proxy 提供参数的文档,但没有解释应该如何使用这些参数。我使用 az aks create 创建我的集群使用 azure-cli 程序,然后我获得凭据并使用 kubect
我想知道与在 PHP 中使用 setcookie() 函数相比,在客户端通过 JavaScript 设置一些 cookie 是否有任何明显的优势?我能想到的唯一原因是减少一些网络流量(第一次)。但不是
我有一个按钮可以将 body class 设置为 .blackout 我正在使用 js-cookie设置cookie,下面的代码与我的按钮相关联。 $('#boToggle').on('click'
我有一堆自定义的 HTML div。我将其中的 3 存储在具有 slide 类的 div 中。然后,我使用该幻灯片类调用 slick 函数并应用如下设置: $('.slide').slick({
我正在创建一个应该在 Windows 8(桌面)上运行的应用 我需要: 允许用户使用我的应用启动“文件历史记录”。我需要找到打开“文件历史记录”的命令行。 我需要能够显示“文件历史记录”的当前设置。
我刚买了一台新的 MacBook Pro,并尝试在系统中设置 RVM。我安装了 RVM 并将默认设置为 ➜ rvm list default Default Ruby (for new shells)
由于有关 Firestore 中时间戳行为即将发生变化的警告,我正在尝试更改我的应用的初始化代码。 The behavior for Date objects stored in Firestore
在 ICS 中,网络 -> 数据使用设置屏幕中现在有“限制后台数据”设置。 有没有办法以编程方式为我的应用程序设置“限制后台数据”? 或 有没有办法为我的应用程序调出具有选项的“数据使用”设置? 最佳
我正在尝试使用 NextJS 应用程序设置 Jest,目前在 jest.config.js : module.exports = { testPathIgnorePatterns: ["/.n
我最近升级到 FlashDevelop 4,这当然已经将我之前的所有设置恢复到原来的状态。 我遇到的问题是我无法在新设置窗口的哪个位置找到关闭它在方括号、大括号等之前插入的自动空格的选项。 即它会自动
有没有办法以编程方式访问 iPhone/iPod touch 设置? 谢谢。比兰奇 最佳答案 大多数用户设置可以通过读取存储在 /User/Library/Preferences/ 中的属性列表来访问
删除某些值时,我需要选择哪些设置来维护有序队列。我创建了带有自动增量和主键的 id 的表。当我第一次插入值时,没问题。就像 1,2,3,4,5... 当删除某些值时,顺序会发生变化,例如 1,5,3.
我正在尝试设置示例 Symfony2 项目,如此处所示 http://symfony.com/doc/current/quick_tour/the_big_picture.html 在访问 confi
我是一名优秀的程序员,十分优秀!