C# 如何优雅地保护方法不受未初始化接口参数的影响
给定接口类型的方法参数,如果使用者可以提供引用类型或未知值类型,即开发人员在实现时不知道的结构类型,我如何保护方法不受未初始化参数的影响?我不想检查传入属性的特定属性值。我已经在这个主题上做了很多搜索,但还没有找到我想要的确切信息 例如 。。。在别的班C# 如何优雅地保护方法不受未初始化接口参数的影响,c#,C#,给定接口类型的方法参数,如果使用者可以提供引用类型或未知值类型,即开发人员在实现时不知道的结构类型,我如何保护方法不受未初始化参数的影响?我不想检查传入属性的特定属性值。我已经在这个主题上做了很多搜索,但还没有找到我想要的确切信息 例如 。。。在别的班 public void DoSomething(IFoo foo) { // Check if foo is null or default of some value type // Just like foo == nul
public void DoSomething(IFoo foo)
{
// Check if foo is null or default of some value type
// Just like foo == null, this doesn't work for a value type
if (foo == default(IFoo)) throw new ArgumentNullException(nameof(foo));
}
当传递给接受此结构实现的接口的方法时,FooStruct将被装箱,因此您可以将其与null进行比较。您可能想阅读有关装箱的内容,本文可能也会有所帮助:FooStruct在传递给接受此结构实现的接口的方法时将被装箱,因此您可以将其与null进行比较。您可能想阅读有关装箱的内容,也许本文也会有所帮助:如果方法不会因为初始化值而实际中断,则不要担心初始化值。与
null
相比就足够了,因为您真正要做的是尝试使用指定的参数名称抛出一个早期异常,而不是可怕且不具体的NullReferenceException
;throw
的全部目的是添加更具体的细节,以便调用实现能够很容易地修复它们所做的错误(或者至少报告一个更知情的、因而更有意义的bug)。一个很好的例子是,由于计数
;,Linq方法不需要费心抛出
这就是说,如果
FooStruct
中存在无效的内容,那么它应该为该无效性抛出一个特定的异常,而不是某种误导性的ArgumentNullException
。例如,考虑<代码>默认(int) <代码> 0 ,<代码> 0 完全有效地传递到某些方法中,而如果不是,我们期望<代码> ArgumentOutOfRange < /C> >(希望具有有效范围),而不是代码> > AgMUMUTNOT/<代码>,我们知道的值是(并且永远不会)。null
如果方法不会因为初始化值而实际中断,则不要担心初始化值。与null
相比就足够了,因为您真正要做的是尝试使用指定的参数名称抛出一个早期异常,而不是可怕且不具体的NullReferenceException
;throw
的全部目的是添加更具体的细节,以便调用实现能够很容易地修复它们所做的错误(或者至少报告一个更知情的、因而更有意义的bug)。一个很好的例子是,由于计数
;,Linq方法不需要费心抛出
这就是说,如果
FooStruct
中存在无效的内容,那么它应该为该无效性抛出一个特定的异常,而不是某种误导性的ArgumentNullException
。例如,考虑<代码>默认(int) <代码> 0 ,<代码> 0 完全有效地传递到某些方法中,而如果不是,我们期望<代码> ArgumentOutOfRange < /C> >(希望具有有效范围),而不是代码> > AgMUMUTNOT/<代码>,我们知道的值是(并且永远不会)。null
对于不可null
的struct
,您可以将您的结构与新的MyStruct()
(下面的Activation.CreateInstance)进行比较
上述代码输出以下内容:
True
False
True
False
对于不可
为空的结构
,您可以将您的结构与新的MyStruct()
(下面的Activation.CreateInstance)进行比较
上述代码输出以下内容:
True
False
True
False
从以下方面对代码进行推理通常是有帮助的
每个方法都有一些先决条件——被调用方应该满足的条件,以及后置条件——方法保证对有效输入执行的条件
例如,在方法中,y除以x
x
显然应该是非零ant,这是一个合理的先决条件。这种情况的后置条件是结果小于或等于提供的y
您只能在有效的输入上保证有效的行为,因此,仅仅因为默认结构值是默认的,就没有意义使用默认结构值——而是使用一些特定和合理的断言
ArgumentNullException
之所以广泛传播,仅仅是因为参数通常是以某种方式使用的,因此验证它们是否为null是有意义的,否则您的方法将失败。根据参数对代码进行推理通常是有帮助的
每个方法都有一些先决条件——被调用方应该满足的条件,以及后置条件——方法保证对有效输入执行的条件
例如,在方法中,y除以x
x
显然应该是非零ant,这是一个合理的先决条件。这种情况的后置条件是结果小于或等于提供的y
您只能在有效的输入上保证有效的行为,因此,仅仅因为默认结构值是默认的,就没有意义使用默认结构值——而是使用一些特定和合理的断言
ArgumentNullException
之所以广泛传播,仅仅是因为参数通常以某种方式使用,因此验证它们是否为null是有意义的,否则您的方法将失败。我不明白问题是什么。您说您不想检查特定属性,并且您已经在检查参数是否为null,所以。。。。问题是什么?我认为如果您通过了default(FooStruct)
,那么您应该假设这就是所通过的。空对象很容易被检测为未初始化的对象,但未初始化的结构和其值相同的结构之间没有区别
True
False
True
False