[c#] 在C#中将类作为参数传递并不总是按预期工作。 谁能解释一下?



Answers

C#中参数的默认约定是按值传递的。 无论参数是class还是struct都是如此。 在class情况下,引用是通过值传递的,而在struct则传递整个对象的浅表副本。

当你进入TestAssignmentMethod ,有两个对一个对象的引用:位于AssignmentTest中的TestAssignmentMethod和位于TestAssignmentMethod testClass 。 如果您要通过testClasstestObj对实际对象进行变异,则两个引用都可见,因为它们都指向相同的对象。 在第一行,尽管你执行

testClass = new TestRefClass() { TestInt = 1 }

这将创建一个新的对象,并将testClass指向它。 这不会改变testObj引用以任何方式指向的位置,因为testClass是独立的副本。 现在有2个对象和2个引用,每个引用指向一个不同的对象实例。

如果你想通过引用语义传递,你需要使用ref参数。

Question

我一直认为带有类类型的方法参数默认作为参考参数传递。 显然情况并非总是如此。 考虑在C#中的这些单元测试(使用MSTest)。

[TestClass]
public class Sandbox
{
    private class TestRefClass
    {
        public int TestInt { get; set; }
    }

    private void TestDefaultMethod(TestRefClass testClass)
    {
        testClass.TestInt = 1;
    }

    private void TestAssignmentMethod(TestRefClass testClass)
    {
        testClass = new TestRefClass() { TestInt = 1 };
    }

    private void TestAssignmentRefMethod(ref TestRefClass testClass)
    {
        testClass = new TestRefClass() { TestInt = 1 };
    }

    [TestMethod]
    public void DefaultTest()
    {
        var testObj = new TestRefClass() { TestInt = 0 };
        TestDefaultMethod(testObj);
        Assert.IsTrue(testObj.TestInt == 1);
    }

    [TestMethod]
    public void AssignmentTest()
    {
        var testObj = new TestRefClass() { TestInt = 0 };
        TestAssignmentMethod(testObj);
        Assert.IsTrue(testObj.TestInt == 1);
    }

    [TestMethod]
    public void AssignmentRefTest()
    {
        var testObj = new TestRefClass() { TestInt = 0 };
        TestAssignmentRefMethod(ref testObj);
        Assert.IsTrue(testObj.TestInt == 1);
    }
}

结果是AssignmentTest()失败,另外两个测试方法通过。 我假设的问题是,分配一个新的实例到testClass参数打破参数引用,但不知何故明确地添加ref关键字修复这一点。

任何人都可以对这里发生的事情给出一个好的,详细的解释吗? 我主要是想扩大我对C#的知识。 我没有任何具体的情况,我试图解决...




我的2美分

当类传递给一个方法时,它的内存空间地址的一个副本正在发送(你正在发送的房子的方向)。 所以在这个地址上的任何操作都会影响房子,但不会改变它自己的地址。 (这是默认)

通过引用传递类(对象)具有传递其实际地址而不是地址副本的效果。 这意味着如果您将新对象分配给通过引用传递的参数,它将更改实际地址(类似于重定位)。 :d

这是我的看法。






Related



Tags

c# c#   reference