2014-10-08 38 views
0

好吧,所以我有動力的問題類型存在財產......我知道他們是潛在的危險,但聽我把話說完。基本上我有一個對象,我們稱它爲Customer。動態物體被「填充」與不應該在傳遞

public class Customer 
{ 
    public int Id { get; set; } 
    public string Type { get; set; } 
    public string Value { get; set; } 
    public bool IsActive { get; set; } 
} 

我有另一個繼承自此對象的對象。讓我們稱它爲重要客戶。

public class ImportantCustomer : Customer 
{ 
    public int SomeOtherValue { get; set; } 
} 

我現在有一種方法可以做到我的魔法,它必須對所給予的任何東西做點什麼。該方法不是上述任一類的一部分。

public void DoTheMagic(dynamic myObject) 
{ 
    //My magic here 
) 

問題是,我會得到一個層對象ImportantCustomer,但我想發送一個Customer對象。所以,我做這樣的事情:

var customer = (Customer)importantCustomer; 

Customer customer = importantCustomer; 

ICustomer customer = importantCustomer; 

做的無論哪種方式,網我說,我不希望同樣的結果。現在我有我想要發送給我的方法的對象,一切都應該是好的(客戶)。然而,我魔法中的部分邏輯使用對象參數調用另一個方法。

public void SomeOtherMethod(object obj) 
{ 
    //More magic 
) 

在這個方法裏面它獲得了對象的所有屬性。當它逐步完成時,它會提供給我'SomeOtherValue'屬性,它位於ImportantCustomer對象中,但我傳入了新的Customer對象,顯然不實現該屬性。爲什麼要添加此屬性?有沒有深入瞭解這種做法是如何造成的?是否有什麼與背景中的引用,導致此屬性顯示,因爲鑄造到客戶類型?

如果我做手工的方式:

var customer = new Customer() 
{ 
    Id = importantCustomer.Id, 
    Type = importantCustomer.Type, 
    Value = importantCustomer.Value, 
    IsActive = importantCustomer.IsActive, 
}; 

它的工作原理打算,我沒有在魔術得到「SomeOtherValue」財產的意識。

我有一個很難找到答案/原因。如果在這裏有答案/解釋,我錯過了,請點我。

謝謝。

編輯1

我不明白爲什麼SomeOtherValue財產投後,仍然會存在。我得到的有參考回事,但下課後,如果我在哪裏可以這樣做:因爲財產不客戶類型存在

var customer = (Customer)importantCustomer; 
var value = customer.SomeOtherValue; // ERROR 

編譯器會生氣。我可能只是錯過了一些重要的東西如何鑄造的作品,我只是不知道它是什麼。

更新

有沒有更好的辦法,比使用AutoMapper或類似,以獲得客戶對象我想這樣的東西我就不必手動將其寫出來其他的?

感謝@Matt布蘭德的解釋是有見地的。

回答

3

該屬性在那裏,因爲它是您傳遞的對象的一部分。當您執行Customer customer = importantCustomer時,您正在複製對仍爲ImportantCustomer的對象的引用。你的「手動」鑄造根本不是鑄造。它正在複製對象。投射不是複製。

所以,當你這樣做:

Customer customer = importantCustomer; 

它仍然是一個重要的客戶,你可以,事實上,它轉換回:

ImportantCustomer important = (ImportantCustomer)customer; 

但如果Customer是一個實際Customer(而不是ImportantCustomer)上面的演員會拋出一個錯誤。

所以沒有財產被「添加」 - 它一直存在。

注意:您能不能做到這一點:由於通過輸入變量Customer所有你保證

Customer customer = importantCustomer; 
int t = customer.SomeOtherValue; 

是變量customer將包含Customer對象或的東西,從它派生。所以編譯器只能知道,變量customer具有Customer的所有屬性和方法。因此,在這種情況下它會給你一個編譯錯誤。這並不意味着customer中的對象不具有SomeOtherValue屬性,只是不能保證。例如,你可以這樣做:

Customer customer = importantCustomer; 
// ...some code 
customer = new Customer(); 
// ...some more code 
int t = customer.SomeOtherValue; // now this is obviously wrong 

而且記住,重新分配customer到一個新的Customer可能在另一個線程發生。你甚至可以在調試器中完成它。

+0

但是如果我這樣做:'var customer =(Customer)importantCustomer'或者其他兩種方式我不能做'customer.SomeOtherValue'編譯器會生氣並做一個「WTF你不能做那個「有點錯誤。編譯完成後,編譯器是否隱藏該屬性或其他內容? – Schanckopotamus 2014-10-08 19:54:09

+0

編譯器將會「生氣」,因爲它知道的那個變量就是它包含一個'Customer'。它不知道它包含'ImportantCustomer',並且直到運行時才知道。 – 2014-10-08 19:59:11