10

我有一个从不返回空对象的方法。我想澄清一下,这样我的 API 的用户就不必编写这样的代码:

if(Getxyz() != null)
{
  // do stuff
}

我怎样才能表现出这种意图?

4

9 回答 9

10

不幸的是,没有办法内置到 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/

于 2009-01-27T18:25:09.827 回答
6

除非您使用基于 System.ValueType 的类型,否则我认为您不走运。最好在函数的 XML/元数据注释中清楚地记录这一点。

于 2009-01-27T18:21:15.623 回答
2

我不知道是否有从 API 执行此操作的最佳实践,因为我仍然会进行防御性编程并检查 null 作为消费者。我认为这仍然是这种情况下的最佳实践,因为我倾向于不相信其他代码总是做正确的事情。

于 2009-01-27T18:25:44.023 回答
2

确保 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
    }
}

上面的例子不会编译。如果使用结构是可以接受的(它成为一种值类型,在堆栈上传递,不能被子类化)那么这可能对你有用。

于 2009-01-27T19:02:56.570 回答
1

我喜欢反过来想:如果我的函数可以返回一个空值,我最好确保函数的用户知道它。

于 2009-01-27T18:49:52.867 回答
0

如果您的用户有您的源代码,使用标准按合同设计 API,例如: http: //www.codeproject.com/KB/cs/designbycontract.aspx可以让事情变得清晰。

否则,您最好的选择是通过文档。

于 2009-01-27T18:22:38.273 回答
0

要么很好地记录它(可能使用 .NET 标准文档系统),要么你必须使用一些 Contract API。这里有一些: http: //geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx http://www.codeproject.com/KB/cs/designbycontract.aspx

于 2009-01-27T18:25:06.707 回答
0

您可以包含一个 Debug.Assert() 方法。虽然这肯定不会强制执行该条件,但它应该明确(连同文档)空值是不可接受的。

于 2009-01-27T18:25:35.630 回答
0

记录它并提供源代码。

于 2009-01-27T18:33:07.533 回答