通过引用传递不工作

问题描述:

我有下面的代码通过引用传递不工作

public interface IEntity 
{ 
// Properties 
    int Id { get; set; } 
} 

public class Container : IEntity 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class Command 
{  
    public void ApplyCommand(ref IEntity entity) 
    { 
     Container c = new Container() { Id = 20 }; 
     entity = c; 
    } 
} 

[TestFixture] 
public class ReferenceTest 
{ 
    [Test] 
    public void Casting_ByRef_Not_ReturningValue() 
    { 
     Container c= new Container(); 
     IEntity entity = c; 
     new Command().ApplyCommand(ref entity);   
     Assert.AreEqual(c.Id, 20);    
    } 
} 

测试失败,不应该通过引用传递允许对象引用的变化?

+0

它是.AreEqual失败还是失败与CCE(类别转换异常)?我知道这可能听起来很奇怪,但试着做一些Console.WriteLine来看看事情发生了什么地方。 – Woot4Moo 2009-11-20 18:00:02

+0

而不是WriteLines,看看TestRunner(www.testdriven.net或rehsarper),它允许您在Debug模式下从IDE内运行测试。 – tobsen 2009-11-20 18:04:16

+0

记住,“ref”并不意味着“通过参考”。它意味着“该方法的参数是对另一个变量的引用(即别名)”。 – 2009-11-20 22:52:10

在测试中,您更改了entity指向的对象,但您正在比较指向的对象c

请记住,在创建时会复制引用,以便创建新的Container,让c成为该对象的引用。然后,您通过将c分配给entity来复制该参考文献。现在entityc指的是同一个对象。您将ref entity传入该方法,从而更改entity但未触及c

Container c= new Container(); 
IEntity entity = c; 
new Command().ApplyCommand(ref entity); 
Assert.AreEqual(entity.Id, 20); 

应该肯定有效。

该引用完美,但参考变量c没有涉及。

如果您运行测试Assert.AreEqual(entity.Id, 20);它会通过。

这个测试工作得很好。您有2个引用(c和实体),它们指向类型为Container的单个对象。当你打电话给ApplyCommand时,你只会改变参考实体的值。参考c不变,仍然指向原始的Container对象。

下面是编写测试,以示区别

Container c= new Container(); 
    IEntity entity = c; 
    new Command().ApplyCommand(ref entity);   
    Assert.IsInstanceOfType(entity, typeof(Container)); 
    c = (Container)entity; 
    Assert.AreEqual(c.Id, 20); 

想尽了办法是:

Assert.AreEqual(entity.Id, 20); 

当你写

IEntity entity = c; 

创建的另一个参考变量与c的地址在里面。这个entity变量是你通过参考方法传递的,而不是c变量。

您正在更改对另一个方法中创建的对象的引用,并且将您的IEntity实例指向该对象。