为方法中的参数赋值NULL

时间:2014-08-06 03:06:21

标签: c#

我知道传递给方法的引用类型可以修改。但我发现它只对参数的成员产生影响,而不是参数本身。这是一个测试:

这是一种参考类型:

class MyClass
{
    public int PropInt { get; set; }

    public string PropStr { get; set; }

    public int FieldInt;

    public string FiledStr;
}

此方法修改其成员:

void MyFun(MyClass myClass)
    {
        myClass.PropInt = 3;
        myClass.FieldInt = 4;
        myClass.PropStr = "c";
        myClass.FiledStr = "d";
    }

这会修改自身(null或new):

void MyFunNull(MyClass myClass)
    {

        myClass = new MyClass();
        //myClass = null;
    }

初​​始化:

MyClass myClass = new MyClass
        {
            PropInt = 1,
            FieldInt = 2,
            PropStr = "a",
            FiledStr = "b"
        };

测试:

---> output {1, 2, "a", "b"}
MyFun(myClass); ---> output {3, 4, "c", "d"}
MyFunNull(myClass); ---> output {3, 4, "c", "d"}

这是怎么回事? 在这种情况下,我必须使用out/ref吗?

1 个答案:

答案 0 :(得分:2)

这是因为参数中对象的引用将在您的方法中保持相同(除非您明确重新分配)。当您只更改其属性时,对原始实例没有任何影响。方法完成后,调用者仍然可以访问原始对象并查看更改的属性。参数中的原始实例与来自调用者的传入引用保持相同。

当您使用新的或重新分配更改参数时,除非您使用outref更改方法签名,否则调用者永远不会知道此更改。

如果您希望调用者知道在方法中重新分配或实例化的引用类型,则需要使用ref keywoard(see msdn

对其进行修改

例如:

public void Foo(ref MyClass bar)
{
   // Caller will get this new instance back
   // after method completes.
   bar = new MyClass()
}

更改参考: 以下示例将参数更改为某些预先存在的本地引用。

private MyClass myLocalBar
public void Foo(ref MyClass bar)
{
   // Caller will get the modified reference
   bar = this.myLocalBar;
}

您还可以使用outmsdn)关键字执行类似的操作。但与ref不同,out将要求您为out参数指定值。在对out参数进行赋值之前尝试完成该方法将生成编译器错误。

public void Foo(out MyClass bar)
{
   // We must assign a value to bar
   bar = new MyClass()
}

以下将生成错误(取消评论最后一行以修复)

public void Foo(out MyClass bar)
{
   // We must assign a value to bar
   // Even null assignment is ok:
   // bar = null;
}

out参数始终保证调用者将返回新的/不同的引用。然而,ref告诉调用者该方法可能修改或不修改原始引用。