为什么泛型接口约束会搞乱扩展方法的使用?

时间:2014-10-07 09:27:12

标签: c# .net generics interface

这个问题我很难解释,所以我嘲笑了一些虚拟代码来显示我遇到的问题。它与扩展方法的通用约束有关。在我的扩展方法中,我需要泛型类(但示例不显示此内容)。我们来看看:

我有两个界面:

public interface IOne { }

public interface ITwo { }

现在我为它们创建一些扩展方法:

public static class Extensions
{
    public static string ParseValue(this ITwo ob)
    {
        return "Two";
    }

    public static string ParseValue<T>(this T obj) where T : class, IOne
    {
        return "One";
    }
}

看起来很好吗?现在我创建了ITwo的实现,它会变得混乱:

public class Two: ITwo
{
    public string Test()
    {
        return this.ParseValue();
    }
}

此类无法编译。我得到以下错误:

  

'GenericProblem.Two'类型不能用作类型参数'T'   通用类型或方法   'GenericProblem.Extensions.ParseValue(T)'。没有隐含的   参考从'GenericProblem.Two'转换为   'GenericProblem.IOne'。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

对于错误,我answered it here

  

我该如何解决这个问题?

在调用this之前,您需要将ITwo转换为ParseValue类型,否则编译器将无法选择正确的匹配。

public class Two : ITwo
{
    public string Test()
    {
        return ((ITwo)this).ParseValue();
    }
}

答案 1 :(得分:0)

似乎很直接给我。

在您的分机课程中:

public static class Extensions
{
    public static string ParseValue(this ITwo ob)
    {
        return "Two";
    }

    public static string ParseValue<T>(this T obj) where T : class, IOne
    {
        return "One";
    }
}

您确实使用了ParseValue<T>方法并对其设置了约束,并指出T必须是IOne类型

在ITwo的实现中,您尝试在对象this上调用扩展方法。 明显的this属于ITwo类型,因此您的扩展方法将不再有效。

只需更改扩展方法的签名,如:

public static string ParseValue<T>(this T obj) where T : class, ITwo

这应该可以解决问题。

修改:

根据原始提问者,解决方案没有编译。 下面是完整的源代码我如何拥有它,这确实编译:

public interface IOne { }

public interface ITwo { }

public static class Extensions
{
    public static string ParseValue(this ITwo ob)
    {
        return "Two";
    }

    public static string ParseValue<T>(this T obj) where T : class, ITwo
    {
        return "One";
    }
}

public class Two : ITwo
{
    public string Test()
    {
        return this.ParseValue();
    }
}