具有两个非相等(唯一)类型的泛型类 [英] A generic class with two non-equal (unique) types

查看:88
本文介绍了具有两个非相等(唯一)类型的泛型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能实现一个受两个唯一通用参数约束的类?



如果不是这样,是因为它没有实现还是因为考虑到语言结构(继承性)不可能实现?



我想要某种形式的东西:

  class BidirectionalMap< T1,T2>其中T1!= T2 
{
...
}

我正在实现双向字典






评论中的短语:


  1. 丹:如果不满足此约束,会有什么负面后果?


  2. Me:然后用户可以使用map [t1]和map [t2]进行索引。如果它们是相同类型,则不会有区别,也没有任何意义。


  3. Dan:编译器实际上允许[两个泛型类型参数定义不同的方法重载],所以我很好奇。 它是否随意选择一种调用方法?



解决方案

扩展示例以突出问题:

 公共类BidirectionalMap< T1,T2> 
{
public void Remove(T1项){}
public void Remove(T2项){}

public static void Test()
{
//此行将编译
var可能是Bad = new BidirectionalMap< string,string>();

//这会导致编译器因模棱两可的调用而失败
可能是Bad.Remove( Something);
}
}

所以答案是,即使您可以t指定约束T1!= T2没关系,因为一旦您尝试执行违反隐式约束的操作,编译器就会失败。它仍然会在编译时捕获失败,因此您可以不受惩罚地使用这些重载。有点奇怪,因为您可以创建地图的实例(甚至可以编写可以适当地操纵地图的IL代码),但是C#编译器不会让您通过任意解决歧义重载而造成严重破坏。

$注意:如果您不小心,这种重载可能会导致某些奇怪的行为。如果您有 BidirectionalMap< Animal,Cat> 和Cat:Animal,请考虑以下代码会发生什么:

 动物= new Cat(); 
map.Remove(animal);

这将调用需要Animal的重载,因此即使您可能打算删除值Cat。这在某种程度上是人为的,但是当方法重载导致非常不同的行为时,足以引起注意。在这种情况下,如果只是给方法指定不同的名称,以反映其不同的行为(例如,RemoveKey和RemoveValue,则可能更容易阅读和维护)。


Is it possible to implement a class constrained to two unique generic parameters?

If it is not, is that because it is unimplemented or because it would be impossible given the language structure (inheritance)?

I would like something of the form:

class BidirectionalMap<T1,T2> where T1 != T2
{
  ...
}

I am implementing a Bidirectional dictionary. This is mostly a question of curiosity, not of need.


Paraphrased from the comments:

  1. Dan: "What are the negative consequence if this constraint is not met?"

  2. Me: "Then the user could index with map[t1] and map[t2]. If they were the same type, there would be no distinction and it wouldn't make any sense."

  3. Dan: The compiler actually allows [two generic type parameters to define distinct method overloads], so I'm curious; does it arbitrarily pick one of the methods to call?

解决方案

Expanding on the example to highlight the problem:

public class BidirectionalMap<T1,T2>
{
    public void Remove(T1 item) {}
    public void Remove(T2 item) {}

    public static void Test()
    {
        //This line compiles
        var possiblyBad = new BidirectionalMap<string, string>();

        //This causes the compiler to fail with an ambiguous invocation
        possiblyBad.Remove("Something");
    }
}

So the answer is that, even though you can't specify the constraint T1 != T2, it doesn't matter, because the compiler will fail as soon as you try to do something that would violate the implicit constraint. It still catches the failure at compile time, so you can use these overloads with impunity. It's a bit odd, as you can create an instance of the map (and could even write IL code that manipulates the map appropriately), but the C# compiler won't let you wreak havoc by arbitrarily resolving ambiguous overloads.


One side note is that this kind of overloading could cause some odd behaviors if you're not careful. If you have a BidirectionalMap<Animal, Cat> and Cat : Animal, consider what will happen with this code:

Animal animal = new Cat();
map.Remove(animal);

This will call the overload that takes Animal, so it will try to remove a key, even though you might have intended to remove the value Cat. This is a somewhat artificial case, but it's enough to warrant caution when very different behaviors occur as a result of method overloading. In such cases, it's probably easier to read and maintain if you just give the methods different names, reflecting their different behaviors (RemoveKey and RemoveValue, let's say.)

这篇关于具有两个非相等(唯一)类型的泛型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆