在C#/ .NET中将参数标记为不可为空?

Nei*_*ski 90 .net c# parameters null

是否有一个简单的属性或数据契约,我可以分配给一个函数参数,以防止null在C#/ .NET中传递?理想情况下,这也会在编译时进行检查,以确保文本null在任何地方都没有被使用,并且在运行时抛出ArgumentNullException.

目前我写的东西像......

if (null == arg)
  throw new ArgumentNullException("arg");
Run Code Online (Sandbox Code Playgroud)

......对于我期望不存在的每一个论点null.

在同一个注释中,是否Nullable<>会出现以下情况:

NonNullable<string> s = null; // throw some kind of exception
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 66

遗憾的是,在编译时没有任何可用的东西.

我最近在我的博客上发布了一些hacky解决方案,它使用了一个新的结构和转换.

在带有Code Contracts的 .NET 4.0中,生活会更好.拥有实际的语言语法和支持非可空性仍然是非常好的,但代码契约将有很大帮助.

我在MiscUtil中也有一个名为ThrowIfNull 的扩展方法,它使它更简单一些.

最后一点 - 使用" if (null == arg)"而不是" if (arg == null)"的任何理由?我发现后者更容易阅读,前者在C中解决的问题不适用于C#.

  • @Thomas.S.Trias:是的,在那个令人难以置信的模糊边缘情况下,*结合*有一个拼写错误,加上缺乏对该代码的测试,你最终会遇到问题.到那时我觉得你有更大的问题:) (11认同)
  • @Jon:当然.我想我会放弃我心爱的尤达条件.:-) (4认同)
  • >遗憾的是,在编译时没有任何可用的东西.> ...>我同意,拥有实际的语言语法和支持非可空性仍然是非常好的.我还想看到引发编译时错误. (2认同)
  • @Jon,如果碰巧有一个隐式转换定义为bool,那么"if(arg = null)"是否有效?我承认它可能看似有悖常理,但它确实编译了...... (2认同)

Gre*_*reg 16

我知道我对这个问题迟到了,但我觉得答案会变得相关,因为C#的最新主要版本接近发布,然后发布.在C#8.0中将发生重大变化,C#将假设所有类型都被视为非空.

根据Mads Torgersen的说法:

问题是空引用非常有用.在C#中,它们是每个引用类型的默认值.默认值还有什么?变量还有什么其他值,直到您可以决定分配给它的其他内容?我们还有什么其他的价值可以铺设新分配的参考数据,直到你开始填写它?

此外,有时null本身就是一个明智的价值.有时你想表示一个事实,比如说一个字段没有值.可以为参数传递"无".但有时重点在于.这就是问题的另一部分:像C#这样的语言不会让你表达这里的null是否是个好主意.

所以Mads概述的决议是:

  1. 我们认为,希望引用不为空是更常见的.可空的引用类型将是罕见的类型(虽然我们没有好的数据告诉我们多少),因此它们应该需要新的注释.

  2. 该语言已经具有 - 可空值类型的概念 - 和语法.两者之间的类比将使语言添加在概念上更容易,并且在语言上更简单.

  3. 你不应该为自己或你的消费者增加繁琐的空值,除非你已经主动决定你想要它们,这似乎是正确的.缺乏,而不是缺少它们,应该是你明确要选择的东西.

所需功能的一个示例:

public class Person
{
     public string Name { get; set; } // Not Null
     public string? Address { get; set; } // May be Null
}
Run Code Online (Sandbox Code Playgroud)

预览适用于Visual Studio 2017,15.5.4+预览.


rse*_*nna 14

我知道这是一个非常古老的问题,但这里缺少这个问题:

如果您使用ReSharper,则可以使用Annotated Framework.


Not*_*tMe 9

查看企业库中的验证器.你可以这样做:

private MyType _someVariable = TenantType.None;
[NotNullValidator(MessageTemplate = "Some Variable can not be empty")]
public MyType SomeVariable {
    get {
        return _someVariable;
    }
    set {
        _someVariable = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您想要验证它的代码中:

Microsoft.Practices.EnterpriseLibrary.Validation.Validator myValidator = ValidationFactory.CreateValidator<MyClass>();

ValidationResults vrInfo = InternalValidator.Validate(myObject);
Run Code Online (Sandbox Code Playgroud)