天真(錯誤?)的想法

最近剛接觸WPF,雖然開發習慣還是像在使用 WinForm

比較近接WPF的用法都還沒使用到

所以想試試看MVVM當中的ViewModel

大致提到 (明確轉型 explicit )和LINQ的Cast限制

以及繼承類別後的轉型問題

還有多載運算子的問題


最近因工作需求開始接觸 WPF

加上本身也在慢慢研究MVC

總覺得未來一定會用到 ViewModel

因此開始在測試及研究 ViewModel該如何去設計

以下的想法是剛接觸這塊區域的新手想的

在OOP上應該本身就不該這樣設計(純粹因為方便而已)

紀錄一下,如未來有人有相同的問題可以參考一下


情境簡單敘述如下:

我在 原始資料 取出的東西是IEnumerable<DBData.Product>

這當中 Model 這是已經包裝好,我無法做修改的 DBData.Product Class

此時我需要對UI 做一些額外的紀錄資訊,如資料操作(新增,修改。顏色要不同)

理所當然想到 做一個 ViewModel 使用 繼承的方式 繼承 DBData.Product 做一個 UIProduct

如: public class UIProduct: DBData.Product

這時候 當未來需要將資料更新回DB 就可以直接使用UIProduct 向上轉型回 DBData.Product 即可

理論上 就可以直接使用 LINQ的 Cast<> 作轉換及可

IEnumerable<UIProduct> => IEnumerable<DBData.Product> 這方向可以,因為是向上轉型

但是

IEnumerable<DBData.Product> => IEnumerable<UIProduct> 這方向就不行 這就變成向下轉型

本以為只需要明確的定義即可達成 轉型

所以如果 當我可以變更 DBData.Product這Class 就可以添加 explicit 去做明確轉型(當初以為這樣做或許我就能向下轉了)

測試結果會是 explicit 無法對衍生類別使用,再寫程式的時候就會提示錯誤

當初因為不能變更DBData.Product這Class 所以在做  explicit 之前 突然想到是否可以使用擴充方法去實作 explicit

Google相關資訊之後發現,網路上已經有人詢問過,也有回答

https://stackoverflow.com/questions/8306614/extension-method-and-explicit-casting

簡單來說就是不行這樣做

擴充方法不可以 作 operator 的覆寫

最多是使用擴充方法 將 DBData.Product提供一個新的方法轉型成為UIProduct

以上問題後來使用其他方式去解決,因為本來以為做了 explicit 之後 就可以使用LINQ 的 Cast 作轉換

結果測試後發現小問題,我猜應該是使用上的限制,Google之後沒找到相關資料可以驗證是什麼原因

網路上有人回答說 LINQ Cast 內部的做法

https://stackoverflow.com/questions/4015930/when-to-use-cast-and-oftype-in-linq

foreach (object obj in source)
    yield return (TResult) obj;

本來以為因為使用 (TResult) 就會去呼叫覆寫後的 explicit 

但是不知道是泛型的關係,單獨使用 覆寫後的 explicit  會成功

但是透過 LINQ Cast 卻無法正確對應(並不會去使用 explicit )

LINQ OfType一樣也會有這問題

這問題因為不清楚關鍵字該如何搜尋,所以還沒找到相關原因(未來有找到再補上)

最後解決方法 只能使用 LINQ  Select(d => (MyUseType)d );

利用這方式將我要的類別轉型出來


結論

  1. 繼承相關類別再做轉型的operator覆寫上,會有限制(會跳出 "衍生類別之間不可進行使用者定義的轉換" 錯誤)
    因為很少去做 explicit 所以一直沒注意到這限制(有興趣的可以順便看 implicitimplicit一樣無法對衍生類別作轉換)
  2. 雖然本來有猜想到 擴充方法 無法對 operator 作覆寫或擴充。不過沒實際去測試過,經由測試後確定的確無法使用
  3. LINQ Cast和 OfType的限制,並不會呼叫 覆寫後的 explicit 
  4. operator 的多載(覆寫) 可參考微軟的資料,本來以為Cast是使用 as 但查詢後 as 也無法多載。
    所以就算真的Cast內部使用 as作轉換,對我目前的使用上意義也不大
  5. 另外 因為VM存在另一個List裡面,為了方便和預計新增的資料作比較所以有 override  Equals。
    VS會提醒說 GetHashCode也要override  原因如微軟所說,為了保證不會出問題強烈建議兩個都 override