在 C# 中,如果泛型类型实现接口,如何获得不同的 IEqualityComparer<T> 实例
In C# how to get different IEqualityComparer<T> instance if generic type implements an interface
我有一个具有无约束泛型类型的泛型方法。如果类型 T 实现接口,我需要获得不同的 IEqualityComparer。
代码大致如下:
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;
}
}
这似乎是模板特化的典型案例,但据我所知,C# 不支持此类功能。我也在考虑 static class 实现一个策略模式来交换函数以获取比较器,但是 static 将对所有类型实现,因此类型-方法字典查找是必要的。为此生成 IL 代码似乎是最后的手段,考虑到代码没有被大量使用,不值得付出努力。
更改相关方法的行为的最佳方法是什么,以便在 T 实现 IMerge 时出现特殊情况?我问是因为理论上应该可以在编译时或至少在初始化时(静态构造函数)定义行为,如果它在运行时不会改变的话。
我认为您现有的代码没有任何问题。我个人会保持原样。
IMO 在你有证据表明它对性能至关重要之前优化它是过早的优化。
如果你真的想缓存比较的结果,你可以使用类似的东西:
static class MergeComparerHelper<T>
{
static bool SupportsMerge = typeof(IMerge).IsAssignableFrom(typeof(T));
}
这利用了每个通用实例都有自己的静态字段这一事实。您可以为此使用私有嵌套 class。
但是请注意,这仍然会产生运行时分派的成本,因为 .NET JITter 的当前实现不会为不同的引用类型 T
生成专门的实现。
我有一个具有无约束泛型类型的泛型方法。如果类型 T 实现接口,我需要获得不同的 IEqualityComparer。
代码大致如下:
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;
}
}
这似乎是模板特化的典型案例,但据我所知,C# 不支持此类功能。我也在考虑 static class 实现一个策略模式来交换函数以获取比较器,但是 static 将对所有类型实现,因此类型-方法字典查找是必要的。为此生成 IL 代码似乎是最后的手段,考虑到代码没有被大量使用,不值得付出努力。
更改相关方法的行为的最佳方法是什么,以便在 T 实现 IMerge 时出现特殊情况?我问是因为理论上应该可以在编译时或至少在初始化时(静态构造函数)定义行为,如果它在运行时不会改变的话。
我认为您现有的代码没有任何问题。我个人会保持原样。
IMO 在你有证据表明它对性能至关重要之前优化它是过早的优化。
如果你真的想缓存比较的结果,你可以使用类似的东西:
static class MergeComparerHelper<T> { static bool SupportsMerge = typeof(IMerge).IsAssignableFrom(typeof(T)); }
这利用了每个通用实例都有自己的静态字段这一事实。您可以为此使用私有嵌套 class。
但是请注意,这仍然会产生运行时分派的成本,因为 .NET JITter 的当前实现不会为不同的引用类型
T
生成专门的实现。