2

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

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

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

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

4

4 回答 4

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>。这样您就可以按预期实现接口,并强烈声明它。

于 2012-06-29T15:17:31.117 回答
1

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

为了实现这个接口,你的类必须允许任何类型用于那个方法。(任何符合interface中定义的约束的类型,在这种情况下,由于没有约束,因此意味着任何类型。)

您不能将接口限制在实现它的特定类中,因为这是一个泛型方法(不是泛型类型),并且没有任何约束可以使其正常工作。

为了做你想做的事,我认为,你需要使接口通用:

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

通过使接口在搜索条件上通用,您允许您的类基于搜索条件的特定类型来实现它。

于 2012-06-29T15:22:10.100 回答
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) {
    ...
  }
}

I think this is a more consistent design, since both generic parameters are at the same level (and it looks like they should go together). But only you can say whether this is better for your code or not.

于 2012-06-29T15:41:33.063 回答
0

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

您的实现不像接口合同那样通用。

于 2012-06-29T15:17:27.210 回答