2009-11-20 68 views
2

我有下面的代碼通過引用傳遞不工作

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

回答

8

在測試中,您更改了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); 

應該肯定有效。

1

該引用完美,但參考變量c沒有涉及。

如果您運行測試Assert.AreEqual(entity.Id, 20);它會通過。

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); 
1

想盡了辦法是:

Assert.AreEqual(entity.Id, 20); 

當你寫

IEntity entity = c; 

創建的另一個參考變量與c的地址在裏面。這個entity變量是你通過參考方法傳遞的,而不是c變量。

1

您正在更改對另一個方法中創建的對象的引用,並且將您的IEntity實例指向該對象。