尝试使用通用扩展方法时没有隐式引用转换

时间:2017-06-29 01:42:16

标签: c# generics constraints extension-methods

即使浏览了堆栈溢出的类似答案,我也在努力理解为什么我遇到问题背后的概念。

我的代码如下:

class Program {
    static void Main(string[] args) {
        HomePage page = new HomePage();
        page.Load(); //No Error
        LoginPage page2 = new LoginPage();
        page2.Load(); //No Error
        ApprenticePage page3 = new ApprenticePage();
        page3.Load(); //No implicit reference conversion
        ApprenticeEPA page4 = new ApprenticeEPA();
        page4.Load(); //No implicit reference conversion
        Console.ReadLine();
    }
}

public abstract class BasePage<T> where T : BasePage<T> {
    public abstract bool EvaluateLoad();
}

public class HomePage : BasePage<HomePage>
{
    public override bool EvaluateLoad()
    {
        Console.WriteLine("In HomePage");
        return true;
    } 
}

public class LoginPage : BasePage<LoginPage>
{
    public override bool EvaluateLoad()
    {
        Console.WriteLine("In LoginPage");
        return true;
    }
}

public class ApprenticePage : HomePage
{
    public override bool EvaluateLoad()
    {
        Console.WriteLine("In ApprenticePage");
        return false;
    }
}

public class ApprenticeEPA : ApprenticePage
{
    public override bool EvaluateLoad()
    {
        Console.WriteLine("In ApprenticeEPA");
        return false;
    }
}

public static class Helper {
    public static T Load<T>(this T page) where T : BasePage<T> {
        if (page.EvaluateLoad()) {
            Console.WriteLine("It's true!");
            return page;
        } else {
            Console.WriteLine("It's false!");
            return default(T);
        }        
    }
}

我收到以下错误:

  

“IndexerTest.ApprenticePage”类型不能用作类型参数   泛型或方法'Helper.Load(T)'中的'T'。没有   从'IndexerTest.ApprenticePage'到。的隐式引用转换   'IndexerTest.BasePage&LT; IndexerTest.ApprenticePage&GT;'。

在我看来,ApprenticePage继承自HomePage,继承自BasePage<T>,使用加载方法会没问题,但显然不是。

如何修复我的Load方法,以便可以在我的代码中的所有类实例上调用它,并使用EvaluateLoad()的类特定实现?

1 个答案:

答案 0 :(得分:2)

如果仔细检查错误,则说明如下:

  

没有从“ApprenticePage”到“BasePage&lt; ApprenticePage&gt;”的隐式引用转换

这是正确的; ApprenticePageBasePage<HomePage>,不是BasePage<ApprenticePage>

您要做的是创建一个扩展方法,该方法适用于实现BaseType<T>的任何内容。因此,您的扩展方法应如下所示:

public static BasePage<T> Load<T>(this BasePage<T> page) where T : BasePage<T>
{
    if (page.EvaluateLoad())
    {
        Console.WriteLine("It's true!");
        return page;
    }
    else
    {
        Console.WriteLine("It's false!");
        return null; // No need for default() here - default() of a reference type is
                     // always going to be null
    }
}