![](/img/trans.png)
[英]What's the reason of using the Object type instead of an actual type for events?
[英]What's the reason of using implicit/explicit convertions instead of constructors?
一個例子是:
XNamespace ns = "my namespace"
為什么不?:
XNamespace ns = new XNamespace ( "my namespace" )
使用隱式/顯式轉換而不是構造函數的背后的想法是什么? 方便?
是否有指導方針?
方便?
或多或少,是的。 考慮當您有一個類似數字的對象(例如Complex
)進行計算時的情況。 顯然,編寫如下代碼:
Complex result = c1 * new Complex(2) + new Complex(32);
非常煩人且難以閱讀。 隱式轉換在這里有幫助(在此示例中,一種替代方法是運算符重載,但這會導致很多類似的重載)。
是否有指導方針?
提供盡可能少的隱式轉換,因為它們可能隱藏問題。 隱式轉換將顯式性降低的程度與其增加簡潔性的程度相同。 有時候這很好,但有時卻不好。
我發現最好將隱式轉換限制為非常相似的類型,例如上面示例中的數字類對象: int
本質上是Complex
(從數學的角度;即使不是通過繼承建模),因此是隱式的轉換很有意義。
在VB中,隱式轉換稱為“ Widening
”(與Narrowing
( explicit
)相反),這很好explicit
描述了這一點:在轉換過程中不會丟失任何信息。
此外,運算符本質上是一個構建器函數,並且具有(某些)構建器函數相對於構造器的通常優點:即,它可以重新使用緩存的值,而不必始終創建新實例。
考慮我的Complex
示例。 我們可能要緩存常用復數的值:
Class Complex {
// Rest of implementation.
private static Complex[] cache = new[] {
new Complex(-1), new Complex(0), new Complex(1) };
public implicit operator Complex(int value) {
if (value >= -1 && value <= 1)
return cache[value];
else
return new Complex(value);
}
}
當然,這種微觀優化是否有效是另一個問題。
我認為,將隱式轉換與XName這樣的簡單類型一起使用的原因之一是調用方法的方便。
例如,你可以寫
var info = root.Elements ("user").Element ("info").Value;
LINQ的目的是簡化數據提取,如果我們不得不寫的話
var info = root.Elements (new XName ("user")).Element (new XName ("info")).Value;
即使是最簡單的查詢,LINQ對於復雜的查詢也完全值得嗎?
這里的另一個重要問題是XName被原子化。 參見MSDN :
保證XName對象被原子化; 也就是說, 如果兩個XName對象具有完全相同的名稱空間和完全相同的本地名稱,則它們將共享相同的instance 。 為此,還明確提供了相等和比較運算符。
除其他好處外,此功能還可以更快地執行查詢。 在過濾元素或屬性的名稱時,謂詞中表示的比較使用身份比較,而不是值比較。 與比較兩個字符串相比,確定兩個引用實際引用同一對象要快得多。
您不能在構造函數中提供原子化,但是定義轉換后,您可以從池中選擇相應的對象,並將其作為新實例返回。
隱式/顯式轉換的使用是方便的問題,許多編程准則都建議您避免使用顯式ConvertToXXX
方法。
問題之一是使用隱式/顯式轉換會進一步重載強制轉換運算符的功能。 它具有雙重目的
不幸的是,C#已經在其他領域(使用基元和裝箱)完成了后者。
如果兩個類可以相互轉換,但它們不共享自動允許此行為的基類的接口,則可以使用轉換。 隱式轉換永遠不會丟失數據; 它們通常被視為“擴大”轉化。 例如,將int
轉換為long
就是擴大的轉換,並且隱式轉換沒有內在的問題。 顯式轉換可能會導致數據丟失; long
可能會轉換為int
,也可能無法轉換為int
,具體取決於其值。
我用於隱式轉換的一個技巧是,當我沒有其他合理的選擇時,將不同名稱空間中的類彼此轉換。 例如,一個WCF服務返回一個AuthenticationToken對象,我需要將該對象傳遞給另一個命名空間中的WCF服務。 兩者都具有這個AuthenticationToken對象,並且進行常量轉換將是一件痛苦的事情。 我的解決方案涉及在部分類中使用public static implicit operator
來添加功能以每種方式進行轉換。
就個人而言,當我知道rhs可能會轉換為類的靜態成員時,我會使用這些轉換(例如說color = "red"
表示color = Colors.Red
)
我打算實際創建新實例時使用new運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.