C# 通用扩展方法装箱转换问题
C# Generic Extension Method Boxing Conversion Issue
我正在研究 migrating/rewriting C# 中的一些 Java 泛型。我收到一个我不明白的错误。
(这部分是一项基于组合而非继承的实验,以限制不需要某些功能的子 classes 的膨胀,但它也只是一个更好地理解 C# 泛型的实验。)
注意:实际的 child-class 实现确实像我预期的那样工作,只是没有编译的扩展方法。
一位家长class:
public abstract class PageObject<T> where T : PageObject<T>
{
protected IWebDriver WebDriver => ServiceLocator.GetWebDriver();
public PageObject()
{
PageFactory.InitElements(WebDriver, this);
}
// ... more stuff, but the constructor is the important thing that keeps
// me using an abstract parent class. There are some abstract methods
// that return T so the child classes can return "this" in a fluent api.
}
一个接口:
public interface IHasCustomLoadCondition<T> where T : PageObject<T>
{
bool IsLoaded();
}
和一个扩展方法,这是错误发生的地方:
public static T WaitForCustomPageLoad<T>(this T page) where T : IHasCustomLoadCondition<T>
{
wait.Until<bool>((d) =>
{
return page.IsLoaded();
});
return page;
}
错误信息:
The type 'T' cannot be used as type parameter 'T' in the generic type or method
'IHasCustomLoadCondition<T>'. There is no boxing conversion or type parameter conversion
from 'T' to 'PageObject<T>'.
既然你有这个声明:
public interface IHasCustomLoadCondition<T> where T : PageObject<T>
^---------------------^
您必须确保您也将此约束带入派生接口,实现 类 和在相同 T
上也通用的方法,因此此方法:
public static T WaitForCustomPageLoad<T>(this T page) where T : IHasCustomLoadCondition<T>
还必须有这个约束:
public static T WaitForCustomPageLoad<T>(this T page)
where T : PageObject<T>, IHasCustomLoadCondition<T>
基本上:
public static T WaitForCustomPageLoad<T>(this T page) where T : IHasCustomLoadCondition<T>
^ ^
| |
+-------- constraints must be compatible ---------+
您对接口和方法的泛型类型约束不明确。
public interface IHasCustomLoadCondition<T> where T : PageObject<T>
这意味着,它可能是这样的,因为您将 PageObject
的泛型类型参数约束为相同的 class:
public TestClass : IHasCustomLoadCondition<PageObject<PageObject<PageObject...
如果不是错误,那么您应该按以下方式修改您的方法声明:
public static T WaitForCustomPageLoad<T, T1>(this T page)
where T : IHasCustomLoadCondition<T1>
where T1 : PageObject<T1>
在原始来源中,您的约束意味着 "Generic type argument should be IHasCustomLoadCondition<IHasCustomLoadCondition<IHasCustomLoadCondition...
"
但是接口的约束意味着 IHasCustomLoadCondition
的泛型类型参数应该是 PageObject
,但是 PageObject
没有实现 IHasCustomLoadCondition
。
我希望,这是可以理解的解释。
我正在研究 migrating/rewriting C# 中的一些 Java 泛型。我收到一个我不明白的错误。
(这部分是一项基于组合而非继承的实验,以限制不需要某些功能的子 classes 的膨胀,但它也只是一个更好地理解 C# 泛型的实验。)
注意:实际的 child-class 实现确实像我预期的那样工作,只是没有编译的扩展方法。
一位家长class:
public abstract class PageObject<T> where T : PageObject<T>
{
protected IWebDriver WebDriver => ServiceLocator.GetWebDriver();
public PageObject()
{
PageFactory.InitElements(WebDriver, this);
}
// ... more stuff, but the constructor is the important thing that keeps
// me using an abstract parent class. There are some abstract methods
// that return T so the child classes can return "this" in a fluent api.
}
一个接口:
public interface IHasCustomLoadCondition<T> where T : PageObject<T>
{
bool IsLoaded();
}
和一个扩展方法,这是错误发生的地方:
public static T WaitForCustomPageLoad<T>(this T page) where T : IHasCustomLoadCondition<T>
{
wait.Until<bool>((d) =>
{
return page.IsLoaded();
});
return page;
}
错误信息:
The type 'T' cannot be used as type parameter 'T' in the generic type or method
'IHasCustomLoadCondition<T>'. There is no boxing conversion or type parameter conversion
from 'T' to 'PageObject<T>'.
既然你有这个声明:
public interface IHasCustomLoadCondition<T> where T : PageObject<T>
^---------------------^
您必须确保您也将此约束带入派生接口,实现 类 和在相同 T
上也通用的方法,因此此方法:
public static T WaitForCustomPageLoad<T>(this T page) where T : IHasCustomLoadCondition<T>
还必须有这个约束:
public static T WaitForCustomPageLoad<T>(this T page)
where T : PageObject<T>, IHasCustomLoadCondition<T>
基本上:
public static T WaitForCustomPageLoad<T>(this T page) where T : IHasCustomLoadCondition<T>
^ ^
| |
+-------- constraints must be compatible ---------+
您对接口和方法的泛型类型约束不明确。
public interface IHasCustomLoadCondition<T> where T : PageObject<T>
这意味着,它可能是这样的,因为您将 PageObject
的泛型类型参数约束为相同的 class:
public TestClass : IHasCustomLoadCondition<PageObject<PageObject<PageObject...
如果不是错误,那么您应该按以下方式修改您的方法声明:
public static T WaitForCustomPageLoad<T, T1>(this T page)
where T : IHasCustomLoadCondition<T1>
where T1 : PageObject<T1>
在原始来源中,您的约束意味着 "Generic type argument should be IHasCustomLoadCondition<IHasCustomLoadCondition<IHasCustomLoadCondition...
"
但是接口的约束意味着 IHasCustomLoadCondition
的泛型类型参数应该是 PageObject
,但是 PageObject
没有实现 IHasCustomLoadCondition
。
我希望,这是可以理解的解释。