我有一个从不返回空对象的方法。我想澄清一下,这样我的 API 的用户就不必编写这样的代码:
if(Getxyz() != null)
{
// do stuff
}
我怎样才能表现出这种意图?
我有一个从不返回空对象的方法。我想澄清一下,这样我的 API 的用户就不必编写这样的代码:
if(Getxyz() != null)
{
// do stuff
}
我怎样才能表现出这种意图?
不幸的是,没有办法内置到 C#
您可以记录这一事实,但这不会被自动检查。
如果您使用的是 resharper,则可以将其设置为在方法标记有 [NotNull] 属性时正确检查。
否则,您可以使用 [Microsoft Contracts][1] 库并在您的方法中添加类似于以下内容的内容,但对于这样一个简单的注释来说,这是相当多的多余的措辞。
Contract.Ensures(Contract.Result<string>() != null)
Spec# 通过允许 ! 在类型之后将其标记为非空类型,例如
string! foo
但是 Spec# 只能用于面向 .NET2,并且已被 Code Contracts 库篡夺。[1]:http ://research.microsoft.com/en-us/projects/contracts/
除非您使用基于 System.ValueType 的类型,否则我认为您不走运。最好在函数的 XML/元数据注释中清楚地记录这一点。
我不知道是否有从 API 执行此操作的最佳实践,因为我仍然会进行防御性编程并检查 null 作为消费者。我认为这仍然是这种情况下的最佳实践,因为我倾向于不相信其他代码总是做正确的事情。
确保 C# 对象从不返回 null 的唯一类型检查方法是使用结构。结构可以有包含空值的成员,但它们本身永远不能为空。
所有其他 C# 对象都可以为空。
示例代码:
public struct StructExample
{
public string Val;
}
public class MyClass
{
private StructExamle example;
public MyClass()
{
example = null; // will give you a 'Cannot convert to null error
}
public StructExample GetXyz()
{
return null; // also gives the same error
}
}
上面的例子不会编译。如果使用结构是可以接受的(它成为一种值类型,在堆栈上传递,不能被子类化)那么这可能对你有用。
我喜欢反过来想:如果我的函数可以返回一个空值,我最好确保函数的用户知道它。
如果您的用户有您的源代码,使用标准按合同设计 API,例如: http: //www.codeproject.com/KB/cs/designbycontract.aspx可以让事情变得清晰。
否则,您最好的选择是通过文档。
要么很好地记录它(可能使用 .NET 标准文档系统),要么你必须使用一些 Contract API。这里有一些: http: //geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx http://www.codeproject.com/KB/cs/designbycontract.aspx
您可以包含一个 Debug.Assert() 方法。虽然这肯定不会强制执行该条件,但它应该明确(连同文档)空值是不可接受的。
记录它并提供源代码。