泛型方法的条件编译

6

目前正在开发一个通用的2向查找关联功能,按TKey排序。希望最终能够像下面这样方便地访问:

public class Assoc<TKey, TValue>
{
     public TKey this[TValue value] { get; }
     public TValue this[TKey value] { get; }
}

但是当TKey == TValue时,这将失败。出于好奇,是否有条件编译语法来实现这个:

public class Assoc<TKey, TValue>
{
     [Condition(!(TKey is TValue))]
     public TKey this[TValue value] { get; }

     [Condition(!(TKey is TValue))]
     public TValue this[TKey value] { get; }

     public TKey Key(TValue value) { get; }

     public TValue Value(TKey value) { get; }
}

在什么情况下使用 TKey == TValue 类会很有用? - casablanca
public TKey this[TValue value] { get; } 是什么作用?我不理解这个 API 的目的。 - Matthew
@casablanca,你有使用过Dictionary<string, string>吗?看起来Jake想要一个非常类似于字典的东西,但是可以通过键和值进行关联搜索。 - Alexei Levenkov
我曾经遇到过类似的问题。在getter中,我只是使用了类似于if value.GetType() == typeof(TKey)这样的语句,并根据情况采取了相应的行动。但我想你已经猜到了替代方案... - Guillaume
@Matthew,这个键是用于排序而不是查找的,与你最初的印象略有不同。 - Jake
1个回答

4
没有,基于泛型类型的条件编译是不可能的。
泛型替换是在运行时执行的,而不是在编译时执行的。
这是.NET泛型和C++模板之间的差异之一。
泛型也没有C++模板所具有的“特化”概念。

http://msdn.microsoft.com/en-us/library/c6cyy67b.aspx


2
+1。注意,“泛型在运行时而非编译时解析”并不完全正确——在编译时,需要正确地找到泛型类中的方法(这正是当编译器尝试选择使用哪个版本的索引器时,Jake的类产生的确切错误)。 - Alexei Levenkov
2
同意@Alexei的观点;这里的问题与泛型的运行时行为无关。这纯粹是一种方法重载解析的问题,它是一个编译时构造。特别是,问题在于没有限定符(例如where TKey: Foo等),编译器将它们都视为object,因此当两个方法共享相同的参数类型(即object)时,正常的方法重载冲突行为就会发生。这是一个编译时间场景。 - Kirk Woll
泛型在C#中也没有C++模板具有的特化概念。在阅读ECMA-335之后,我相信CLI本身确实允许对泛型进行特化(尽管这需要一定程度的语言支持)。 - Dai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接