2014-03-26 11 views
1

有一個很大的代碼庫,我試圖在這裏處理。一旦問題出現,根據我所想要知道的數據對象是與一些參數,一個結構即形式:c#中的類型意外的行爲,不能重鑄到一個結構

public struct MyData 
{ 
    public float A; 
    public float B; 
} 

有這些類型的集合,但是當我鑽到這些條目中的每一個條目都應該有這些類型之一,我發現雖然我正在查看上面的基礎結構,但我不能使用「點形式」,比如說object.A來獲取它的價值。當我嘗試將其轉換爲結構時,我得到一個問題,因爲我指向的對象說這是一個不同的類型,但是在查看它時是正確的格式。我認爲這可能與被定義爲集合有關

var outputData = new myCollection<Tstuff>(); 

這是cast語句。

var myCast = (MyData) MyObject.Value; 

我得到一個問題,我無法將類型轉換爲Tstuff到MyData。因爲它懸停在MyObject上,所以它的類型是KeyValuePair。

但是在調試時,奇怪的是在Visual Studio即時窗口允許我這樣做,比如我就可以做到以下幾點:

myCast.A 

和問題返回浮動。這兩個問題是:

1)爲什麼我不能做演員時object.Value是正確類型的明確 - 確定當我使用.GetType()

2)爲什麼我可以做演員在Visual Studio的直接窗口中,但不在代碼的主體中。

在此先感謝。很抱歉,很難發佈。這是一個龐大的代碼集,我只是參與其中。

下面是一些謎題的附加部分:

var outputData = new myCollection<Tstuff>(); 

縱觀定義MyCollection的,我們得到如下:

public class myCollection<Tstuff> : BaseTransferValueCollection<string, Key, Tstuff> 
    { 
     public myCollection(); 
    } 

如果我們深入到該繼承的類:

public abstract class BaseTransferValueCollection<TP, TKey, TValue> : Dictionary<TP, IList<KeyValuePair<TKey, TValue>>> 
{ 


} 

這裏是添加過程:

dResults.Add(new KeyValuePair<Key, MyData>(
            new Key(kvpS.Key, id), 
            new MyData 
            { 
             A = 100.00, 
             B = 200.00,  
            })); 

對不起,它不容易追蹤代碼中的東西。因此,要總結:

的MyObject如下所示,當我們將鼠標懸停在它:

{[ida:765687645, idb:463786843, xxx.xxx.xxx.MyData]} 
+1

您可以使用Tstuff中的where子句,以便強制執行所有Tstuff條目都將實現某個允許您獲取MyData值的接口的規則嗎? – Ted

+0

@泰德,你能擴展嗎? – disruptive

+1

如果您無法更改任何內容以添加約束,請嘗試先將其轉換爲對象:var myCast =(MyData)(object)MyObject.Value;然而,這是非常危險的代碼,如果你在這個泛型集合中使用了除MyData以外的其他東西,它將會中斷。 – Ted

回答

0

試試這個:

var myCast = ((MyData) MyObject).Value; 

說明:一組額外的括號來表示您正在鑄造MyObject作爲MyData,然後訪問.Value成員。否則,您試圖將MyObject.Value轉換爲MyData。

編輯

我重新讀您的文章。這可能不完全是答案。你可以發佈多一點的代碼 - 你可以包括字典對象的定義,一些將你的結構添加到字典中的代碼,以及試圖將它從字典中提取出來的代碼?

+0

可悲的是這不起作用。我現在來看看更多的代碼。我正在努力處理代碼庫和嵌套數據結構的龐大規模。 – disruptive

+0

我現在已經完成了......上面。我希望這有幫助 – disruptive

0

C#使用單個類型轉換語法(Foo)bar來表示許多不同的操作。其中:

  • 使用原始指令在某些類型間編譯器生成的轉換[例如, (double)12.3f將生成「convert float to double」指令]。
  • 調用的源或目標類型
  • 定義的任何轉換,操作員功能重讀參考作爲不同類型的它已經已知(例如String類型的值鑄造Object類型的值)
  • 確保一個引用類型的特定值也是另一個引用類型的值,並將其重新解釋爲後一類型或拋出異常。
  • 取一個值,如果它不是堆引用,則生成一個包含該值的新堆對象並返回一個引用。
  • 獲取堆引用,確保它標識指定類型的對象,並根據指定類型需要返回引用或由此標識的對象的內容。

編譯器可以使用任何任意類型的X和Y,沒有單個「convert type X to type Y」操作。編譯器必須能夠識別需要上述哪些轉換才能生成正確的碼。請注意,編譯器可以使用第五種方法處理所有轉換爲Object,使用第六種方法處理來自Object的所有轉換,因此向對象添加中間轉換將允許編譯代碼,即使編譯器不知道相關類型。但是請注意,編譯成功並不意味着執行成功或有效。一起使用第五和第六種方法的嘗試將始終進行編譯,但如果實際上前兩種方法中的一種是必需的,它將在運行時失敗。

如果有一種方法,通過該代碼可以說,這將是有益的:

// Hypothetical syntax: "converts var x = y as z" tries to convert y to type z 
// and if it works, defines label x to the result 

if (converts var temp = myThing as System.Drawing.Point) 
{ 
    temp.X = 4; 
} 
else 
{ 
    // Can't do conversion 
} 

的.NET剛剛在即時編譯器的仿製藥處理機制,但不能如果一般處理這樣的構造-type myThing可能是一個值類型;如果例如myThing是一個int,它會產生一個看起來像代碼:

if (typeof(Int32) == typeof(System.Drawing.Point)) 
{ 
    System.Drawing.Point temp = myThing; // Illegal 
} 

即使代碼不會在事實上執行和它因此不會有問題,如果有的話,分配產生什麼樣的代碼中,JIT ,沒有任何機制可以讓JITter簡單地省略不可能的賦值語句。它必須產生一個可行的任務,如果不這樣做,將不得不完全拒絕該構造。