用于设置为新实例的C#扩展方法(如果为null) [英] C# extension method for setting to new instance if null

查看:75
本文介绍了用于设置为新实例的C#扩展方法(如果为null)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下扩展方法可以帮助我检查和实例化对象是否为空.前两个工作正常,但它们不是很有用.

I have the following extension methods to help me check and instantiate objects if they are null. The top two work just fine but they are not very useful.

    public static bool IsNull<T>(this T t)
    {
        return ReferenceEquals(t, null);
    }

    public static T NewIfNull<T>(this T t, Func<T> createNew)
    {
        if (t.IsNull<T>())
        {
            return createNew();
        }

        return t;
    }

    public static void Ensure<T>(this T t, Func<T> createNew)
    {
        t = t.NewIfNull<T>(createNew);
    }

最终我想做类似的事情

IList<string> foo;
...
foo.Ensure<IList<string>>(() => new List<string>());

但是,确保方法无法达到预期的效果,如果将foo设置为List<string>的实例,则将其设置为null,否则将其设置为List<string>.

The Ensure method however does not achieve the desired effect, which is setting foo to a instance of List<string> if it is null and basically set it to itself otherwise.

如果您现在知道,我可以调整确保"方法来实现这一点,我将感谢您的帮助.

if you know now I can tweak the Ensure method to achieve this I would appreciate the help.

谢谢汤姆

推荐答案

您需要区分对象变量.对象永远不能为null-变量的值可以为null.您不是要更改某个对象的某些内容(将起作用的工作),而是要更改调用方变量的值.

You need to distinguish between objects and variables. An object can never be null - the value of a variable can be. You're not trying to change something about an object (which would work) - you're trying to change the value of the caller's variable.

但是,默认情况下,参数会按值传递,这意味着您的扩展方法会更改 parameter (方法中声明的变量),但这对调用方的变量.通常,您可以将参数更改为ref以获得通过引用的语义,但是扩展方法不能具有refout的第一个参数.

However, arguments are passed by value by default, which means that your extension method changes the parameter (the variable declared within the method), but this has no effect on the caller's variable. Normally you'd be able to change the parameter to ref to achieve pass-by-reference semantics, but extension methods can't have a ref or out first parameter.

就像其他人所说的那样,使用 null-coalescing运算符(??)是更好的选择.请注意,在此表达式中:

As others have said, using the null-coalescing operator (??) is a better bet. Note that in this expression:

foo = foo ?? new List<string>();

除非foo为空,否则不会构造 新列表.除非需要,否则不评估??的右侧操作数.

the new list is not constructed unless foo is null. The right hand operand of ?? is not evaluated unless it needs to be.

这篇关于用于设置为新实例的C#扩展方法(如果为null)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆