使用2个Type参数的显式泛型方法实现 - 仅显式命名1 Type Parameter

时间:2012-06-29 15:11:31

标签: c# .net

我有一个接口,它有一个带有两个类型参数的泛型方法。我想部分地在类中明确地实现该泛型方法。这可能吗?下面是一些示例代码:

public interface ISomeInterface
{
    TResultType Results<TResultsType,TSearchCriteriaType>(TSearchCriteriaType searchCriteria);
}

public class SomeConcrete : ISomeInterface
{
    public TResultsType Results<TResultsType, ConcreteSearchCriteria>(ConcreteSearchCriteria searchCriteria)
{
    return (TResultsType)Results;
}
}

我是否必须明确地实现两个类型参数才能使其工作?

4 个答案:

答案 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)

是的,我认为你这样做,否则你没有直接实现界面。

您的实施不像界面合同那样通用。