2011-12-12 105 views
2

我聲明爲這樣一類:我可以創建自定義暗示類型演員嗎?

public abstract class CrmAttribute <T> : ICrmAttribute 
{ 

} 

而在所述方法的一個進一步向下我有此

castedValue = (T)value; 

castedValue然後在作爲參數T類型的其他方法中使用。

我的問題是已經出現這樣的情況,以上投拋出InvalidCastException

從我可以告訴這是一個具體的情況;在Dynamics 2011中,微軟終於擺脫了類似CRMNumber這樣的自定義類型,並且轉向了固有的.Net類型,但並非所有情況。剩下的那些,是一個複雜的Money類型,它有一個屬性.Value,它包含一個小數。這是我的異常拋出的地方,因爲我不能將小數轉換爲Money類型。儘管Money對象本質上是Decimal

我對泛型還是比較新的,大部分都是遺傳代碼,所以我很清楚正確的響應是不是這樣做,但我所要做的就是能夠創建我自己暗示的Money轉換爲Decimal,以便使用T的行將正確投射。

這可能嗎?

回答

2

最好的辦法是在演員身邊添加代碼,以測試T是否是有問題的類型並執行適當的轉換而不是依賴演員表。

也許是這樣的:

if (typeof(Money).IsAssignableFrom(typeof(T)) 
{ 
    // special handling required to convert decimal to money 
    castedValue = new Money() { Value = value }; // ? best guess 
} 
else 
{ 
    castedValue =(T)value; 
} 
+0

我做了這樣的事情,但它不會在行上編譯'if(T是Money)'錯誤是'T'是'類型參數',但像'變量'一樣使用,我不'確定如何循環瀏覽,因爲我仍然在泛泛而談自己。 – Chris

+1

'T'是一個類型參數,所以你不能像'is'那樣在它上面使用一個實例操作符。出於同樣的原因,你不能寫'DateTime是對象' - 它沒有任何意義。比較兩種類型的方法是使用代表它們的'Type'類。您可以通過使用'typeof(T)'或'myInstanceOfT.GetType()'來實現'Type'類的實例。前者用於編譯時已知類型(例如泛型),後者用於運行時已知類型。所以只需使用'if(typeof(T)== typeof(Money))'。 –

+0

@AllonGuralnek小心:如果'Money'被解除密封,並且該對象可能是派生類的實例,則測試類型相等性將不起作用。 – phoog

0

由於存在多種不同的貨幣,您應該會希望不能將小數轉換爲貨幣類型。

您不能將隱式轉換添加到其他類型,除非它在類型本身中聲明。你將不得不做一些明確的投射。

+0

我意識到這不是理想的行爲,但在應用程序的階段,它的價值是重要的一部分。我會做明確的轉換,但是與其他答案一樣,我不確定如何特別在其他方法後面將'castedValue'作爲類型T,並且明確地將其從T轉換爲'Money'時,我再次遇到錯誤。 – Chris

0

你不能做到以下幾點:

public partial class Money 
{ 
    public static implicit operator Money(decimal d) 
    { 
    // do whatever code in here you want to change your decimal into the money type 
    } 
} 

我不是說這是一個好主意,但如果錢不是值類型和不密封這應該是可能的。

+2

部分類使類定義跨越多個源文件,而不是多個程序集。除非您在單個項目中包含部分類的所有部分,否則您無法以這種方式擴展類,因爲'Money'是Microsoft提供的類,所以他不會這樣做。 –

相關問題