在 C#/.NET 中将参数标记为不可为空?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/291340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mark parameters as NOT nullable in C#/.NET?
提问by Neil C. Obremski
Is there a simple attribute or data contract that I can assign to a function parameter that prevents null
from being passed in C#/.NET? Ideally this would also check at compile time to make sure the literal null
isn't being used anywhere for it and at run-time throw ArgumentNullException
.
是否有一个简单的属性或数据协定可以分配给防止null
在 C#/.NET 中传递的函数参数?理想情况下,这也会在编译时进行检查,以确保文字null
没有在任何地方用于它和在运行时 throw ArgumentNullException
。
Currently I write something like ...
目前我写的东西像......
if (null == arg)
throw new ArgumentNullException("arg");
... for every argument that I expect to not be null
.
...对于我希望不是的每一个论点null
。
On the same note, is there an opposite to Nullable<>
whereby the following would fail:
同样,Nullable<>
以下是否会失败:
NonNullable<string> s = null; // throw some kind of exception
采纳答案by Jon Skeet
There's nothing available at compile-time, unfortunately.
不幸的是,在编译时没有可用的东西。
I have a bit of a hacky solutionwhich I posted on my blog recently, which uses a new struct and conversions.
我最近在我的博客上发布了一些hacky 解决方案,它使用了新的结构和转换。
In .NET 4.0 with the Code Contractsstuff, life will be a lot nicer. It would still be quite nice to have actual language syntax and support around non-nullability, but the code contracts will help a lot.
在 .NET 4.0 和代码契约的东西中,生活会好很多。拥有实际的语言语法并支持非可空性仍然会很好,但代码契约将有很大帮助。
I also have an extension method in MiscUtilcalled ThrowIfNull which makes it a bit simpler.
我在MiscUtil 中还有一个名为 ThrowIfNull的扩展方法,这使它更简单一些。
One final point - any reason for using "if (null == arg)
" instead of "if (arg == null)
"? I find the latter easier to read, and the problem the former solves in C doesn't apply to C#.
最后一点 - 使用“ if (null == arg)
”而不是“ if (arg == null)
”的任何理由?我发现后者更容易阅读,前者在 C 中解决的问题不适用于 C#。
回答by NotMe
Check out the validators in the enterprise library. You can do something like :
查看企业库中的验证器。您可以执行以下操作:
private MyType _someVariable = TenantType.None;
[NotNullValidator(MessageTemplate = "Some Variable can not be empty")]
public MyType SomeVariable {
get {
return _someVariable;
}
set {
_someVariable = value;
}
}
Then in your code when you want to validate it:
然后在您想要验证它的代码中:
Microsoft.Practices.EnterpriseLibrary.Validation.Validator myValidator = ValidationFactory.CreateValidator<MyClass>();
ValidationResults vrInfo = InternalValidator.Validate(myObject);
回答by Jeff Grizzle
not the prettiest but:
不是最漂亮的,但是:
public static bool ContainsNullParameters(object[] methodParams)
{
return (from o in methodParams where o == null).Count() > 0;
}
you could get more creative in the ContainsNullParameters method too:
您也可以在 ContainsNullParameters 方法中获得更多创意:
public static bool ContainsNullParameters(Dictionary<string, object> methodParams, out ArgumentNullException containsNullParameters)
{
var nullParams = from o in methodParams
where o.Value == null
select o;
bool paramsNull = nullParams.Count() > 0;
if (paramsNull)
{
StringBuilder sb = new StringBuilder();
foreach (var param in nullParams)
sb.Append(param.Key + " is null. ");
containsNullParameters = new ArgumentNullException(sb.ToString());
}
else
containsNullParameters = null;
return paramsNull;
}
of course you could use an interceptor or reflection but these are easy to follow/use with little overhead
当然你可以使用拦截器或反射,但这些很容易遵循/使用,开销很小
回答by Martin Capodici
Ok this reply is a bit late, but here is how I am solving it:
好的,这个回复有点晚了,但这是我解决它的方法:
public static string Default(this string x)
{
return x ?? "";
}
Use this exension method then you can treat null and empty string as the same thing.
使用此扩展方法,您可以将空字符串和空字符串视为同一件事。
E.g.
例如
if (model.Day.Default() == "")
{
//.. Do something to handle no Day ..
}
Not ideal I know as you have to remember to call default everywhere but it is one solution.
我知道并不理想,因为您必须记住在任何地方调用默认值,但这是一种解决方案。
回答by rsenna
I know this is a VERY old question, but this one was missing here:
我知道这是一个非常古老的问题,但是这里缺少这个问题:
If you use ReSharper/Rider you may use the Annotated Framework.
如果您使用 ReSharper/Rider,您可以使用Annotated Framework。
Edit: I just got a random -1 for this answer. That's fine. Just be aware it is stillvalid, even though it's not the recommended approach for C#8.0+ projects anymore (to understand why, see Greg's answer).
编辑:我刚刚得到了一个随机的 -1 这个答案。没关系。请注意它仍然有效,即使它不再是 C#8.0+ 项目的推荐方法(要了解原因,请参阅Greg 的回答)。
回答by Greg
I know I'm incredibly late to this question, but I feel the answer will become relevant as the latest major iteration of C# comes closer to release, then released. In C# 8.0 a major change will occur, C# will assume alltypes are considered not null.
我知道我对这个问题的回答太晚了,但我觉得随着 C# 的最新主要迭代接近发布,然后发布,答案将变得相关。在 C# 8.0 中将发生重大变化,C# 将假定所有类型都被视为非空。
According to Mads Torgersen:
根据 Mads Torgersen 的说法:
The problem is that null references are so useful. In C#, they are the default value of every reference type. What else would the default value be? What other value would a variable have, until you can decide what else to assign to it? What other value could we pave a freshly allocated array of references over with, until you get around to filling it in?
Also, sometimes null is a sensible value in and of itself. Sometimes you want to represent the fact that, say, a field doesn't have a value. That it's ok to pass “nothing” for a parameter. The emphasis is on sometimes, though. And herein lies another part of the problem: Languages like C# don't let you express whether a null right here is a good idea or not.
问题是空引用是如此有用。在 C# 中,它们是每个引用类型的默认值。还有什么默认值?一个变量还有什么其他值,直到你可以决定分配给它什么?在你开始填充它之前,我们还能用什么其他值来铺满一个新分配的引用数组?
此外,有时 null 本身就是一个合理的值。有时您想表示一个事实,例如,一个字段没有值。可以为参数传递“无”。不过,重点是有时。这就是问题的另一部分:像 C# 这样的语言不允许您表达此处的 null 是否是一个好主意。
So the resolution outlined by Mads, is:
因此,Mads 概述的决议是:
We believe that it is more common to want a reference not to be null. Nullable reference types would be the rarer kind (though we don't have good data to tell us by how much), so they are the ones that should require a new annotation.
The language already has a notion of – and a syntax for – nullable value types. The analogy between the two would make the language addition conceptually easier, and linguistically simpler.
It seems right that you shouldn't burden yourself or your consumer with cumbersome null values unless you've actively decided that you want them. Nulls, not the absence of them, should be the thing that you explicitly have to opt in to.
我们认为更常见的是希望引用不为空。可空引用类型将是较少见的类型(尽管我们没有好的数据告诉我们有多少),因此它们是应该需要新注释的类型。
该语言已经有了可空值类型的概念和语法。两者之间的类比将使语言添加在概念上更容易,在语言上更简单。
除非您主动决定需要它们,否则您不应该用繁琐的 null 值给自己或您的消费者带来负担,这似乎是正确的。空值,而不是它们的缺失,应该是您明确必须选择的事情。
An example of the desired feature:
所需功能的示例:
public class Person
{
public string Name { get; set; } // Not Null
public string? Address { get; set; } // May be Null
}
The preview is available for Visual Studio 2017, 15.5.4+ preview.
预览版可用于 Visual Studio 2017 15.5.4+ 预览版。