我有以下代码
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 :(得分:8)
在测试中,您更改entity
指向的对象,但您正在比较指向的对象c
。
请记住,引用会在赋值时被复制,因此您可以创建新的Container
,让c
成为对该对象的引用。然后,通过将c
分配给entity
来复制该引用。现在,entity
和c
都指向同一个对象。您将ref entity
传递给方法,从而更改了entity
但未触及c
。
Container c= new Container();
IEntity entity = c;
new Command().ApplyCommand(ref entity);
Assert.AreEqual(entity.Id, 20);
一定能奏效。
答案 1 :(得分:2)
这个测试工作得很好。您有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);
答案 2 :(得分:1)
引用完美,但不涉及引用变量c
。
如果您运行测试Assert.AreEqual(entity.Id, 20);
,它将通过。
答案 3 :(得分:1)
试试这个:
Assert.AreEqual(entity.Id, 20);
写作时
IEntity entity = c;
在堆栈上创建另一个引用变量,其中包含c
的地址。这个entity
变量是你通过引用方法传递的,而不是c
变量。
答案 4 :(得分:1)
您正在更改对在另一个方法中创建的对象的引用,并且您将IEntity实例指向该对象。