c#静态类中的8个可为空的引用类型
Posted
技术标签:
【中文标题】c#静态类中的8个可为空的引用类型【英文标题】:c# 8 nullable reference types in static class 【发布时间】:2020-03-23 15:51:00 【问题描述】:我对静态类中的 C# 8 可空引用类型有疑问。这是我的原始代码。
public static class Foo
private static IFactory _factory;
public static void Init(IFactory factory) => _factory = factory;
public static string GetVersion() => _factory.GetVersion();
现在我有一个警告
私有静态 IFactory _factory; //非空字段未初始化。考虑将该字段声明为可为空。
这是正确的,因为不调用Init()
,_factory
将是null
。但我会在程序一开始就打电话给Init()
。
所以我将其设为可空 private static IResultFactory? _factory;
并且警告消失了。
但我又收到了一个警告
公共静态字符串 GetVersion() => _factory.GetVersion(); //取消引用可能为空的引用。
在这里我知道,当我到达这里时,它不会是null
,除了! (null-forgiving) operator
之外还有其他优雅的方式吗?
或者我还缺少什么来解决这个问题?
更新:我知道一个方法有一些技巧和窍门,例如:
internal static T NotNull<T>([NotNull] this T? value) where T : class =>
value ?? throw new ArgumentNullException(nameof(value));
这里是说返回不会是null
,只是为了摆脱警告。
我想知道有没有类似的东西。
【问题讨论】:
我的第一个想法是使用空对象模式或静态构造函数。另外我必须说这有点像服务定位器,我不喜欢这样使用静态类。 @LeisenChang 你能解释一下什么是空对象模式吗? 为什么不接受第二个警告呢?您说您将始终在程序开始时调用 Init ......这意味着如果您不这样做,将会抛出异常,这可能是您想要的。异常告诉您某些内容不正确,因此无法继续执行。 你的初始化不是线程安全的,所以它已经有问题了。正如已经建议的那样,您应该使用静态构造函数,或者System.Lazy<IFactory>
【参考方案1】:
首先我认为可以使用空对象模式:
public static class Foo
private static IFactory _factory = new NullFactory();
public static void Init( IFactory factory ) => _factory = factory;
public static string GetVersion() => _factory.GetVersion();
public interface IFactory
string GetVersion();
public class NullFactory : IFactory
public string GetVersion()
return string.Empty;
如果IFactory不一定是从外部传入,也可以考虑静态构造函数。
public static class Foo
private static IFactory _factory;
static Foo()
_factory = new Factory();
public static string GetVersion() => _factory.GetVersion();
但毕竟我不喜欢使用静态类,除了扩展方法。我建议将 IFactory 分配给任何需要它的类。
【讨论】:
以上是关于c#静态类中的8个可为空的引用类型的主要内容,如果未能解决你的问题,请参考以下文章