2010-09-29 196 views
8

隱含的操作有什麼錯誤使用隱式操作如下所示:泛型類型

//linqpad c# program example 
void Main() 
{ 
    var testObject = new MyClass<int>() { Value = 1 }; 

    var add = 10 + testObject; //implicit conversion to int here 
    add.Dump(); // 11 
} 

class MyClass<T> 
{ 
    public T Value { get; set; } 
    public static implicit operator T (MyClass<T> myClassToConvert) 
    { 
     return myClassToConvert.Value; 
    } 
} 

我想我可以當作這樣的對象作爲一個值類型的實例,但看到我從來沒有見過這樣的例子我想也許有一個原因而不是做這樣的事情,有人可以指出?

在我的實際代碼中,我正在考慮將其作爲數據抽象層的一部分,以便我可以用描述底層數據的信息返回對象,但允許邏輯代碼將它視爲值類型需要知道的是價值,同時保持一切都很好,並與泛型保持一致。

回答

10

如果所有以下爲真:

  • MyClass<T>類型的所有可能值(包括null如果它不是一個值類型!)地圖的T

  • 有效值

    隱式操作符永遠不會拋出(即使對於null也不會拋出!)

  • 隱式操作符nversion使語義有意義並且不會讓客戶程序員感到困惑

然後這沒什麼不對。當然你可能做這三件事情中的任何一件,但它會是糟糕的設計。特別是,拋出的隱式運算符可能非常難以調試,因爲調用它的地方並不會說它正在被調用。

例如,認爲T?沒有隱式轉換爲T(其中T當然是值類型)。如果存在這樣的隱式運算符,那麼當T?爲空時將不得不拋出明顯的值,因爲沒有明顯的值將null轉換爲的任何值類型T


讓我舉個例子,我有麻煩的調試,其中隱含的運營商拋出一個問題:

public string Foo() 
{ 
    return some_condition ? GetSomething() : null; 
} 

這裏,GetSomething返回類型我寫了一個用戶定義的隱式轉換的東西到string。我絕對確定GetSomething永遠不會返回null,但我得到了NullReferenceException!爲什麼?因爲上面的代碼是不相當於

return some_condition ? (string)GetSomething() : (string)null; 

return (string)(some_condition ? GetSomething() : (Something)null); 

現在你可以看到那裏的null來自哪裏!

+0

我不知道我理解周圍可空類型的關注......在我看來,如果你有N =新MyClass的(){值= NULL};消費代碼試圖做類似int i = n;並且它會拋出相同的異常,以至於任何不良的轉換會發生,對於可空類型來說沒什麼特別的。 – asawyer 2010-09-29 15:58:12

+0

@asawyer:這只是一個例子。想象一下,沒有'T'和*你*必須實現你自己的'Nullable '。你會給它一個隱式轉換爲'T'嗎?我的回答解釋了爲什麼你不應該這樣做,爲什麼* real *'T?'沒有。 – Timwi 2010-09-29 16:02:43

+0

我現在看到,首先是這些問題引發了這個問題。看起來我可以繼續前進,但要非常謹慎。 – asawyer 2010-09-29 16:12:21

1

這是一個很好的模式。請記住,要將其用作T類型的變量,您必須明確將其轉換爲T,或將其分配給類型爲T的變量。演員將在方法調用和其他事情(例如您的添加示例)中自動發生,其中包含T

Implicit conversion without assignment?

+0

這是不正確的。 – Timwi 2010-09-29 15:39:39

+0

@Timwi,你確定嗎? 'MyClass myClass',在這一點上,'myClass。*'只會解析'MyClass '上的成員,而不是'T'。你必須像arootbeer提到的那樣做,並且執行'((T)myClass)。*'以便通過'T'本身訪問任何成員。 – 2010-09-29 15:43:35

+0

我幾天前就問過這個問題。 http://stackoverflow.com/questions/3703555/implicit-conversion-without-assignment – arootbeer 2010-09-29 15:44:40