c# - 如果您可以创建不可为空的引用类型怎么办?

标签 c# .net struct nullable non-nullable

您是否曾经需要通知任何使用您的代码并传递一些引用类型参数的人不要传递 null?你肯定有。并且您应该为您的代码无法使用的每个“坏”变量抛出异常。

现在,假设您已经创建了这个结构:

public struct NotNullable<T> where T : class
{
    // Backing field for the value. Guaranteed to return not null.
    private T _value;
    public T Value
    {
        get
        {
            if (_value == null)
                throw new ApplicationException("Value is not initialized.");

            return _value;
        }
    }

    // Easy both-ways convertible.
    public static implicit operator T(NotNullable<T> notNullable)
    {
        return notNullable.Value;
    }
    public static implicit operator NotNullable<T>(T value)
    {
        return new NotNullable<T>(value);
    }

    // These members are overridden.
    public override string ToString()
    {
        return Value.ToString();
    }
    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }
    public override bool Equals(object obj)
    {
        if (obj is NotNullable<T>)
        {
            return Value.Equals(((NotNullable<T>)obj).Value);
        }

        return Value.Equals(obj);
    }

    public NotNullable(T value)
    {
        this._value = value;
    }
}

这种结构的用法:

class Program
{
    static void Main(string[] args)
    {
        NotNullable<string> a = "Hello World!";

        Console.WriteLine(a);
        Console.WriteLine((string)a);
        Console.WriteLine((object)a);
        Console.WriteLine((NotNullable<string>)a);

        // Produces fine outputs.


        var b = default(NotNullable<string>); 
        Console.WriteLine(b); // Throws an exception of non-initialized field.
    }
}

您还可以使您的方法接收不可为空的引用类型参数:

List<Tree> treeList;

public void CreateTree(NotNullable<Tree> tree)
{
    // Assume you cannot have the list contain nulls.
    treeList.Add(tree); // No null-checks required.
}

Nullable<> 如此有用的对立面可能有什么问题?结构?

最佳答案

我不明白这对 throw 有什么好处ArgumentNullException 。事实上,我宁愿这样做:

public void Foo(MyClass item, MyClass2 item2)
{
    if (item == null)
        throw new ArgumentNullException("item");

    if (item2 == null)
        throw new ArgumentNullException("item2");
}

这样我就可以让程序员知道哪个参数是错误的。与NotNullable<T>我想它会是这样的:

public void Foo(NotNullable<MyClass> item, NotNullable<MyClass> item2) { ... }

Foo((NotNullable<MyClass>)myVar1, (NotNullable<MyClass2>)myVar2);

现在我得到"Value is not initialized."扔到我脸上。哪一个?

关于c# - 如果您可以创建不可为空的引用类型怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18125413/

相关文章:

c# - 一种选择特定随机名称的方法

c# - 如何将两个 Entity Framework 调用合并为一个?

asp.net - 孤立的 RazorEngine 无法将模型传递到不同的 AppDomain

arrays - 二维数组快速进入表格 View

c - 通过函数传递动态数组结构

c# - 将数量封装在结构中以实现类型安全会对性能产生影响吗?

c# - 程序集未找到 NEWBIE 问题

.net - 如何使用 DevCenter 远程连接到 Cassandra

c# - 如何在 MVC .Net 中的 session 超时后重定向?

C++:使用 memset 还是结构构造函数?什么是最快的?