2017-07-24 71 views
3

我有一個在WinForms中使用了多年的擴展方法,但沒有嘗試在新的WPF項目中使用它。方法:如何避免此InvalidCastException?

public static String GetDescription(this Enum value) 
{ 
    //var info = value.GetType().GetField(value.ToString()); 
    //if (info != null) 
    //{ 
    // var attributes = (DescriptionAttribute[])info.GetCustomAttributes(typeof(DescriptionAttribute), false); 
    // if (attributes != null && attributes.Length > 0) 
    //  return attributes[0].Description; 
    //} 
    //return value.ToString(); 

    var info = value.GetType().GetField(value.ToString()); 
    var attributes = Attribute.GetCustomAttributes(info); 
    if (attributes.Length > 0 && (attributes[0] is System.ComponentModel.DescriptionAttribute)) 
     return ((System.ComponentModel.DescriptionAttribute)attributes[0]).Description; 
    return value.ToString(); 
} 

第一個塊(即被註釋掉)是原始方法。第二塊是與我一起測試的稍微不同的版本。如果我強迫返回符合投來執行,我得到這個異常:

InvalidCastException image

異常的從對話全文:

附加信息:[A]系統.ComponentModel.DescriptionAttribute不能轉換爲[B] System.ComponentModel.DescriptionAttribute。類型A來源於位於'C:\ TFS_Local \ Antero \ AnteroWPF \ bin \ Debug \ System.ComponentModel'上下文'Default'中的'System.ComponentModel.Primitives,Version = 4.1.1.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a' .Primitives.dll」。類型B來源於位於'C:\ WINDOWS \ Microsoft.Net \ assembly \ GAC_MSIL \ System \ v4.0_4.0.0'上下文'Default'中的'System,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089' .0__b77a5c561934e089 \ System.dll中」。

涉及的兩個組件似乎是:

System.ComponentModel.Primitives.dll(它存在於構建bin目錄...不完全知道如何到達那裏)

System.dll(直接從GAC參考,對於明顯原因)

我完全迷失在這裏。如果我刪除了ComponentModel DLL,那就成爲例外。儘管例外聲稱System具有類型,但似乎沒有可能使用它。即System.ComponentModel.DescriptionAttribute在沒有相應的DLL的情況下似乎不是一個有效的事情。所以,如果我刪除一個失敗,另一個完全無法使用...那麼爲什麼這個異常甚至發生?!

編輯: 我認爲這是值得什麼,如果我檢查的內存attributes的價值,我看到陣列確實有一個單一的項目,它是System.ComponentModel.DescriptionAttribute類型。

+0

與投行 – DonBoitnott

+0

它正常工作對我來說:https://github.com/heldersepu/csharp-proj/commit/c80e3e9828cb08c11cd17031fa10e6a4852878da#diff-225b67798e354b1ad8b608f72aa1ded5 – HelderSepu

+0

@HelderSepu雖然你的例子實際上是不完整的(你的枚舉值做沒有描述屬性),它偶然以這種簡單的形式工作。不幸的是,這對我來說並不明顯。 – DonBoitnott

回答

2

如果我刪除ComponentModel DLL,變得異常

什麼成爲例外呢?

你得到的異常是100%清楚的:項目引用的兩個不同的程序集定義了相同的類型System.ComponentModel.DescriptionAttribute。這種類型is documented as being defined in System.dll。所以System.ComponentModel.Primitives.dll大會似乎是一個可疑的。

有點網絡搜索引導我到這個System.ComponentModel.Primitives NuGet package。從這個描述來看,這似乎與.NET Core有關,事實上,它有一個implementation of that type in the .NET Core source code

在編譯時,程序集似乎已放置在您的構建目錄C:\TFS_Local\Antero\AnteroWPF\bin\Debug中。所以,問題是,如果你正在構建一個WPF程序,爲什麼你在構建目錄中有一個.NET Core程序集?你有沒有在某個時候安裝NuGet軟件包?您的構建目錄包含根目錄TFS_Local,這表明您可能會參加Team Foundation Server存儲庫。是否有可能同事爲您的構建安裝了該軟件包?

我還沒有看到任何讓我相信你可以將桌面.NET Framework與.NET Core混合搭配的東西。所以我認爲簡單的答案就是「不要那樣做」。如果沒有System.ComponentModel.Primitives.dll程序集引用,您可能會收到一些其他錯誤,但您需要解決這些問題。我不知道有什麼理由相信您應該能夠使用.NET Core DLL編譯桌面WPF程序。

如果你相信否則,如果你能解釋爲什麼你認爲你可以在你的WPF程序中使用.NET Core程序集,你是如何做的以及你採取了哪些步驟來確保.NET Core中聲明的類型不會與桌面.NET Framework程序集中聲明的類型衝突,包括System.dll

+0

最後,你的猜測是另一個團隊成員爲改變做出了貢獻。提供枚舉的程序集被設計爲「便攜式」,以便與移動項目一起工作,並導致原始DLL被吸入,導致異常(以及我對它如何到達那裏的困惑)。 – DonBoitnott

0

要解決此問題,請清空bin和obj文件夾。將來自GAC的參考文件的本地副本設置爲false。