[英]Is it possible to constrain a generic type parameter to String OR Array
簡而言之:是否可以定義一個泛型方法,其中類型參數( T
)被約束為string
或int[]
? 在偽C#中,我想要做的是:
public static int MyMethod<T> ( T arg1, T arg2 )
where T : (has an indexer that returns an int) {
// stuff with arg1[i], arg2[j], etc...
}
請注意,在C#中,由於內置string
索引器(返回一個char
)以及從char
到int
隱式轉換,以下表達式意味着source
是string
還是int[]
完全相同:
int someval = source[index];
根據線程將Constrain泛型擴展方法用於基類型和字符串我意識到我不能只在where T : x...
constraint子句中創建一個無關聯類型的列表。 int[]
和string
都符合T: IEnumerable<int>
,但IEnumerable<T>
不要求實現者擁有索引器,這正是我在兩種類型中使用的常見功能。
這背后的目的是我正在構建一些高度優化的字符串解析和分析功能,例如Damerau-Levenshtein距離算法的快速實現。 我發現,首先將我的字符串轉換為int數組有時會在重復的逐字符處理中產生明顯更快的執行(與DL算法一樣)。 這主要是因為比較int
值比比較char
值要快得多。
操作詞是“有時”。 有時,直接在字符串上操作更快,並避免首次轉換和復制到int
數組的成本。 所以我現在擁有除聲明之外真正相同的方法。
當然我可以使用dynamic
,但運行時檢查的性能損失完全破壞了方法構造中的任何收益。 (我做過測試)。
不,C#不允許您創建這樣的“復合”約束。
你展示的表達方式意味着同樣的事情,但你不能利用這個事實來發揮你的優勢。 C#泛型在語法上類似於C ++模板,但它們的工作方式完全不同,因此索引器執行相同操作的事實最終變得無關緊要。
當然,您可以使用您需要的特定類型創建兩個重載,但這確實意味着一些煩人的復制和粘貼。 任何試圖抽象以避免重復的嘗試都會使你的表現嚴重受損。
你不能有一個約束,說“類型必須有一個索引器”。
但是,您可以使用一個約束,指出“類型必須實現具有索引器的接口”。 例如,這樣的接口可能是IList<char>
。
不幸的是, string
沒有實現IList<char>
,所以你必須為它編寫一個小的包裝類:
sealed class StringWrapper : IList<char>
{
public string String { get; private set; }
public StringWrapper(string str) { String = str; }
public static implicit operator StringWrapper(string str)
{
return new StringWrapper(str);
}
public char this[int index]
{
get { return String[index]; }
set { throw new NotSupportedException(); }
}
// Etc.... need to implement all the IList<char> methods
// (just throw NotSupportedException except in the ones that are trivial)
}
然后你可以像這樣聲明你的方法:
public static TElement MyMethod<TCollection, TElement>(TCollection arg)
where TCollection : IList<TElement>
{
return arg[0];
}
[...]
MyMethod<StringWrapper, char>("abc") // returns 'a'
MyMethod<int[], int>(new[] { 1, 2, 3 }) // returns 1
你可以讓你的方法簽名
public static int MyMethod<T> ( T[] arg1, T[] arg2 )
並在傳遞字符串參數之前使用String.ToCharArray()(或者在重載時,你得到了想法...)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.