一个具有两个非泛型的泛型类

是否可以实现一个受限于两个唯一通用参数的类?

如果不是,那是因为它没有实现,或者因为语言结构(继承)而不可能?

我想要一些形式:

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

我正在实现一个双向字典。 这主要是好奇心问题,而不是需要。


从评论中解释:

  • 丹:“如果这个限制没有得到满足,会有什么负面影响?”

  • 我:“然后用户可以使用map [t1]和map [t2]来索引,如果它们是相同的类型,那么就没有区别,这是没有任何意义的。”

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


  • 扩展示例以突出问题:

    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");
        }
    }
    

    所以答案是,即使你不能指定约束T1!= T2,也没有关系,因为只要你试图做一些违反隐式约束的事情,编译器就会失败。 它仍然在编译时捕获失败,所以你可以使用这些重载而不受惩罚。 这有点奇怪,因为你可以创建一个地图实例(甚至可以编写IL代码来适当地操作地图),但C#编译器不会让你通过任意解决模糊的重载而造成破坏。


    一方面请注意,如果你不小心,这种重载可能会导致一些奇怪的行为。 如果您有BidirectionalMap<Animal, Cat>和Cat:Animal,请考虑此代码会发生什么情况:

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

    这将调用带有Animal的重载,所以它会尝试删除一个键,即使您可能打算删除值Cat。 这是一个有些人为的情况,但是当由于方法重载而出现非常不同的行为时,请谨慎行事。 在这种情况下,如果你给这些方法不同的名字,反映它们的不同行为(比如RemoveKey和RemoveValue),读取和维护可能更容易。


    类型约束似乎是不恰当的。 虽然它们约束了类型参数,但目的是让编译器知道该类型可用的操作。
    如果你想,你可以有一个约束,其中T1和T2都来自单独的具体基类,但我不认为这就是你想要的。


    不平等无助于编译器捕捉错误。 当你指定对类型参数的约束时,你告诉编译器这种类型的变量将总是支持某个接口,或者将以某种方式运行。 其中每一个都允许编译器验证更多的东西,比如“这个方法将会出现,所以它可以在T上调用”。

    类型参数的不等式更像是验证方法参数不为null。 它是程序逻辑的一部分,而不是其类型安全。

    链接地址: http://www.djcxy.com/p/9917.html

    上一篇: A generic class with two non

    下一篇: Recommended strategies for backing up appengine datastore