在C#如何获得不同的IEqualityComparer<;T>;实例,如果泛型类型实现接口
我有一个无约束泛型类型的泛型方法。如果类型T实现了一个接口,我需要获得一个不同的IEqualityComparer 代码大致如下所示:在C#如何获得不同的IEqualityComparer<;T>;实例,如果泛型类型实现接口,c#,generics,template-specialization,C#,Generics,Template Specialization,我有一个无约束泛型类型的泛型方法。如果类型T实现了一个接口,我需要获得一个不同的IEqualityComparer 代码大致如下所示: public SomeState MergeCollection<T>( ICollection<T> thisValue, ICollection<T> otherValue, SomeStrategy strategy = SomeStrategy.Default, IEquality
public SomeState MergeCollection<T>(
ICollection<T> thisValue,
ICollection<T> otherValue,
SomeStrategy strategy = SomeStrategy.Default,
IEqualityComparer<T> comparer = null)
{
comparer = comparer ?? GetComparer<T>(strategy);
// code using comparer
}
public IEqualityComparer<T> GetComparer<T>(SomeStrategy strategy)
{
if(typeof(IMerge).IsAssignableFrom(typeof(T)))
{
return GetMergeComparer<T>(strategy);
}
else
{
return EqualityComparer<T>.Default;
}
}
publicsomestate合并集合(
i收集此值,
i收集其他值,
SomeStrategy=SomeStrategy.Default,
IEqualityComparer比较器=空)
{
比较器=比较器??获取比较器(策略);
//使用比较器的代码
}
公共IEqualityComparer GetComparer(SomeStrategy)
{
if(typeof(IMerge).IsAssignableFrom(typeof(T)))
{
返回GetMergeComparer(策略);
}
其他的
{
返回EqualityComparer.Default;
}
}
似乎是模板专业化的典型案例,但据我所知,C#不支持此类功能。我还考虑过静态类实现一种策略模式,以交换用于获取比较器的函数,但是静态类将为所有类型实现,因此类型方法字典查找是必要的。为此生成IL代码似乎是万不得已的办法,考虑到代码的使用量并不是很高,不值得为此付出努力
如果T实现了IMerge,那么改变有问题的方法的行为从而得到特例的最佳方法是什么?我这样问是因为理论上,如果行为在运行时不会改变,应该可以在编译时或至少在初始化时(静态构造函数)定义行为
static class MergeComparerHelper<T>
{
static bool SupportsMerge = typeof(IMerge).IsAssignableFrom(typeof(T));
}
静态类合并比较器帮助
{
静态bool SupportsMerge=typeof(IMerge).IsAssignableFrom(typeof(T));
}
这使用了一个事实,即每个泛型实例化都有自己的静态字段。您可以为此使用私有嵌套类
但是请注意,这仍然会产生运行时调度的成本,因为.NET抖动的当前实现不会为不同的引用类型T
s生成专门的实现您现有的代码有什么问题?虽然您可以将
typeof(IMerge).IsAssignableFrom(typeof(T))
缓存在静态ConditionalWeakDictionary
中,但这不太值得费事,也可能不会提高那么多性能。我在最后添加了说明。它使用反射来改变编译时已知的行为,因此原则上它不被认为是一个好的代码。问题是类本身不是泛型的,只是方法是泛型的。我想这将需要创建一个单独的通用静态比较器工厂类,该类具有用于获取比较器的属性。似乎很难:)我将保留1,但2看起来是一个合理的方法,我肯定会保留书签,以用于更复杂/需要更多优化的通用类/方法专业化的特殊情况。它还显示了C#在这一领域的局限性。我会等几天,以防万一。谢谢你的帮助。