我有一个接口,它有一个带有两个类型参数的泛型方法。我想部分地在类中明确地实现该泛型方法。这可能吗?下面是一些示例代码:
public interface ISomeInterface
{
TResultType Results<TResultsType,TSearchCriteriaType>(TSearchCriteriaType searchCriteria);
}
public class SomeConcrete : ISomeInterface
{
public TResultsType Results<TResultsType, ConcreteSearchCriteria>(ConcreteSearchCriteria searchCriteria)
{
return (TResultsType)Results;
}
}
我是否必须明确地实现两个类型参数才能使其工作?
答案 0 :(得分:1)
我认为这就是你要找的东西:
public class SomeConcrete : ISomeInterface
{
TResultsType ISomeInterface.Results<TResultsType, TSearchCriteriaType>(TSearchCriteriaType searchCriteria)
{
return Results<TResultsType>((ConcreteSearchCriteria)(object)searchCriteria);
}
public TResultsType Results<TResultsType>(ConcreteSearchCriteria searchCriteria)
{
// return something
}
}
请注意,这会在运行时失败,尽管编译器看不到任何问题:
ISomeInterface someInterface = new SomeConcrete();
var result = someInterface.Results<object, SomeOtherSearchCriteria>(null);
更一般地说,您不再像预期的那样实现接口。您可能想要ISomeInterface<TResultsType, TSearchCriteriaType>
,然后制作SomeConcrete<TResultsType> : ISomeInterface<TResultsType, ConcreteSearchCriteria>
。这样你就可以按预期实现接口,并强烈声明它。
答案 1 :(得分:1)
我是否必须明确地实现两个类型参数才能使其工作?
为了实现此接口,您的类必须允许 ANY 类型用于该方法。 (适合接口中定义的约束的任何类型,在这种情况下,因为没有约束,所以表示任何类型。)
您不能在实现它的特定类中限制接口,因为这是一个通用方法(不是泛型类型),并且没有任何约束导致它正常工作。
为了做你想做的事,我想,你需要使接口通用:
public interface ISomeInterface<TSearchCriteriaType>
{
TResultType Results<TResultsType>(TSearchCriteriaType searchCriteria);
}
然后您可以将其实现为:
public class SomeConcrete : ISomeInterface<ConcreteSearchCriteria>
{
public TResultsType Results<TResultsType>(ConcreteSearchCriteria searchCriteria)
{
var results = GenerateResults();
return (TResultsType)results;
}
}
通过在搜索条件上使接口具有通用性,您允许您的类根据搜索条件的特定类型实现它。
答案 2 :(得分:1)
您无法专门化这样的通用方法。如果它在接口中是通用的,则它必须在实现类中是通用的。如果将类型参数移动到界面本身,则可以执行此操作(并且您还可以使用方差注释,使其在结果类型中变为协变,在搜索条件类型中使用逆变):
public interface ISomeInterface<out TResultsType, in TSearchCriteriaType> {
TResultsType Results(TSearchCriteriaType searchCriteria);
}
public class SomeConcrete<TResultsType> :
ISomeInterface<TResultsType, ConcreteSearchCriteria> {
public TResultsType Results(ConcreteSearchCriteria searchCriteria) {
...
}
}
现在你的类在结果类型上是通用的。
您还可以拥有一个专门处理某种结果类型的类,并且在条件类型中具有通用性:
public class IntSearcher<TSearchCriteriaType> :
ISomeInterface<int, TSearchCriteriaType> {
public int Results(TSearchCriteriaType searchCriteria) {
...
}
}
我认为这是一个更一致的设计,因为两个通用参数都在同一级别(看起来它们应该在一起)。但只有你可以说你的代码是否更好。
答案 3 :(得分:0)
是的,我认为你这样做,否则你没有直接实现界面。
您的实施不像界面合同那样通用。