方法重载和泛型参数

4

我阅读了这个问题,并尝试做类似的事情:

static class ExtentionMethods
{
    static public void MyReset<T>(this T col)
    {
        Console.WriteLine("Not a collection!");
    }

    static public void MyReset<T, U>(this T col) where T : ICollection<U>
    {
        col.Clear();
        Console.WriteLine("Cleared!");
    }

    // and maybe more overload for T : IWhatevetInterface<U>
}

这样,实现了ICollection<T>List<T>和其他类会选择第二个方法,而没有实现ICollection接口的类(比如MyClass)则会选择第一个方法,例如:

List<int> list1 = new List<int>();
list1.MyReset<List<int>, int>(); // "Cleared!"
MyClass x = new MyClass(); 
x.MyReset(); // "Not a collection!"

它的功能很好,但问题是,我如何避免为list1.MyReset<List<int>, int>()编写<List<int>, int>?我想简单地写list1.MyReset()
目标是保持区分ICollection<T>和其他类的能力,但也不明确提供泛型参数。
回应评论:我计划添加更多重载,因此情况不仅限于Yes-CollectionNot-Collection

3
为什么不直接取消“非集合”重载呢?这样就可以在编译时避免出现错误的代码,而不是在运行时出错。 - Blorgbeard
@Blorgbeard 我计划添加更多的重载,例如T : IResetableT: IWhateverYouLike等等; 因此,我需要让它们匹配到精确的重载。 - Marson Mao
1个回答

4

C#在其类型推断算法中不使用泛型约束。

然而,看起来你实际上并不需要类型约束。你可以像这样简化你的代码,它是有效的:

static public void MyReset(this object col)
{
    Console.WriteLine("Not a collection!");
}

static public void MyReset<T>(this ICollection<T> col)
{
    col.Clear();
    Console.WriteLine("Cleared!");
}

static public void MyReset<T>(this IWhateverYouLike<T> col)
{
    col.ClearItIfYouLike();
    Console.WriteLine("Cleared!");
}

抱歉,我的错误在于没有澄清有超过两种可能性,请查看我编辑后的问题。 - Marson Mao
你仍然可以有超过两种可能性 - 请看我的编辑。这对你有用吗? - Blorgbeard
@MarsonMao 这个答案确实是唯一可行的方法。你的使用情况并没有太多意义——既然你明确表示只想查找 ICollection<T> 类型,为什么还要使用模板呢? - Rob
@Blorgbeard 我测试了你的解决方案,看起来正是我需要的,谢谢!我没有意识到我可以在一般情况下使用非泛型版本! - Marson Mao
@Rob 你是什么意思?模板方法的哪个部分是错误的? - Marson Mao

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