简体   繁体   English

为什么通用接口约束会混淆扩展方法的使用?

[英]Why does generic interface constraint mess up the use of extension methods?

This problem is very difficult for me to explain, so I mocked up some dummy code to show the problem I encountered. 这个问题对我来说很难解释,因此我模拟了一些虚拟代码来显示遇到的问题。 It has to do with generic constraints on extension methods. 它与扩展方法的一般约束有关。 Within my extension method I need the generic class (but the example does not show this). 在我的扩展方法中,我需要通用类(但示例未显示此内容)。 Let's dive in: 让我们潜入:

I have two interfaces: 我有两个界面:

public interface IOne { }

public interface ITwo { }

Now I create some extension methods for them: 现在,我为它们创建一些扩展方法:

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

Looks fine right? 看起来不错吧? Now I create an implementation of ITwo and it'll get messy: 现在,我创建了一个ITwo的实现,它将变得混乱:

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

This class doesn't compile. 此类无法编译。 I get te following error: 我得到以下错误:

The type 'GenericProblem.Two' cannot be used as type parameter 'T' in the generic type or method 'GenericProblem.Extensions.ParseValue(T)'. 在通用类型或方法“ GenericProblem.Extensions.ParseValue(T)”中,类型“ GenericProblem.Two”不能用作类型参数“ T”。 There is no implicit reference conversion from 'GenericProblem.Two' to 'GenericProblem.IOne'. 没有从“ GenericProblem.Two”到“ GenericProblem.IOne”的隐式引用转换。

How can I solve this problem? 我怎么解决这个问题?

For the error, I've answered it here . 对于错误,我已经在这里回答了

How can I solve this problem? 我怎么解决这个问题?

You need to cast this as ITwo type before calling ParseValue , otherwise compiler will not be able to choose the right match. 你需要施放thisITwo调用之前类型ParseValue ,否则编译器将无法选择合适的搭配。

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

Seems pretty straight forward to me. 对我来说似乎很直接。

In your extension class: 在扩展类中:

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

You do have the method, ParseValue<T> and you put a constraint on it, saying that T must be of type IOne 您确实具有方法ParseValue<T>并对其施加了约束,说T必须为IOne类型IOne

In your implementation of ITwo, you try to call the extension method on the object this . 在ITwo的实现中,您尝试在对象this上调用扩展方法。 Obvious this is of type ITwo so your extension method will not work anymore. 显然, thisITwo类型的,因此您的扩展方法将不再起作用。

Just change the signature of your extension method like: 只需更改扩展方法的签名即可,例如:

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

That should do the trick. 这应该够了吧。

Edit: 编辑:

According to the original questioner, the solution did not compile. 最初的提问者认为,该解决方案未编译。 Underneath is the full source code how I have it and this does compile: 下面是我拥有的完整源代码,它可以编译:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对接口使用约束泛型 - Use constraint generic with interface 为什么 List 使用显式接口方法实现来实现非泛型接口方法? - Why does List use an explicit interface method implementation to implement non-generic interface methods? 如何使用通用接口作为通用约束? - How to use generic interface as generic constraint? 针对通用接口还是作为通用约束创建扩展方法? - Creating an extension method against a generic interface or as a generic constraint? 使用接口作为具有新约束的泛型类型 - Use interface as generic type with new constraint C#如何在接口中使用泛型约束 - C# how to use generic constraint with interface 如何以不那么繁琐的方式编写带有约束的通用接口的扩展方法 - How to write in a less cumbersome way an extension method for generic Interface with a constraint 具有接口作为类型约束的泛型类的c#扩展方法 - c# extension method for a generic class with interface as type constraint 为什么是Generic <T> 具有“where T:class”约束的方法接受接口 - Why does a Generic<T> method with a “where T : class” constraint accept an interface 为什么接口不起作用,但抽象 class 对通用 class 约束起作用? - Why doesn't an interface work but an abstract class does with a generic class constraint?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM