【问题标题】:Implement an Interface with Generic Methods使用通用方法实现接口
【发布时间】:2010-11-23 14:25:47
【问题描述】:

我在这个上画了一个空白,似乎找不到我之前写的任何例子。我正在尝试用一个类实现一个通用接口。当我实现该接口时,我认为有些东西不能正常工作,因为 Visual Studio 不断产生错误,说我没有实现通用接口中的所有方法。

这是我正在处理的内容的存根:

public interface IOurTemplate<T, U>
{
    IEnumerable<T> List<T>() where T : class;
    T Get<T, U>(U id)
        where T : class
        where U : class;
}

那么我的班级应该是什么样子?

【问题讨论】:

  • 问题标题错误。普通类和接口中有泛型方法,有方法的泛型接口也有。

标签: c# generics interface


【解决方案1】:

你应该重新设计你的界面,像这样:

public interface IOurTemplate<T, U>
        where T : class
        where U : class
{
    IEnumerable<T> List();
    T Get(U id);
}

然后,您可以将其实现为泛型类:

public class OurClass<T,U> : IOurTemplate<T,U>
        where T : class
        where U : class
{
    IEnumerable<T> List()
    {
        yield return default(T); // put implementation here
    }

    T Get(U id)
    {

        return default(T); // put implementation here
    }
}

或者,你可以具体实现:

public class OurClass : IOurTemplate<string,MyClass>
{
    IEnumerable<string> List()
    {
        yield return "Some String"; // put implementation here
    }

    string Get(MyClass id)
    {

        return id.Name; // put implementation here
    }
}

【讨论】:

  • 完美。我知道我必须指定通用变量,但不记得在哪里(不是双关语)。谢谢里德!
  • 期望的结果可能是不可能的,但 IMO 这个答案没有泛型方法,而是具有依赖方法的泛型类。从技术上讲,泛型方法似乎有自己的模板参数。
  • 你是对的。问题标题错误,但问题的答案很好。
  • 你可以像这样使用Activator创建T的实例:T obj = Activator.CreateInstance();
  • @ReedCopsey,class 中的 where T : class 是否表示任何类别?这个关键字通常用于创建类,为什么在这里使用它?为什么不写where T : object
【解决方案2】:

我想你可能想像这样重新定义你的界面:

public interface IOurTemplate<T, U>
    where T : class
    where U : class
{
    IEnumerable<T> List();
    T Get(U id);
}

我认为您希望方法使用(重用)声明它们的泛型接口的泛型参数;并且您可能不想让它们使用自己的(不同于接口的)泛型参数使它们成为泛型方法。

给定我重新定义的接口,您可以像这样定义一个类:

class Foo : IOurTemplate<Bar, Baz>
{
    public IEnumerable<Bar> List() { ... etc... }
    public Bar Get(Baz id) { ... etc... }
}

或者像这样定义一个泛型类:

class Foo<T, U> : IOurTemplate<T, U>
    where T : class
    where U : class
{
    public IEnumerable<T> List() { ... etc... }
    public T Get(U id) { ... etc... }
}

【讨论】:

  • 您也可以将其实现为泛型类,即: class Foo : IOurTemplate -- 我不确定 Jason 选择了哪个选项。
【解决方案3】:

-- 编辑

其他答案更好,但请注意,如果您对它的外观感到困惑,您可以让 VS 为您实现接口。

如下所述。

嗯,Visual Studio 告诉我它应该是这样的:

class X : IOurTemplate<string, string>
{
    #region IOurTemplate<string,string> Members

    IEnumerable<T> IOurTemplate<string, string>.List<T>()
    {
        throw new NotImplementedException();
    }

    T IOurTemplate<string, string>.Get<T, U>(U id)
    {
        throw new NotImplementedException();
    }

    #endregion
}

请注意,我所做的只是编写界面,然后单击它,然后等待弹出小图标让 VS 为我生成实现:)

【讨论】:

  • 请参阅:尽管您在接口中专门化了 TU(它们都是 string),但方法本身是泛型的,具有自己的单独/不同的泛型参数...可能不是 OP 的意图。
  • 我同意,我认为你的建议很好,我只是在展示如何让 VS 为你实现接口,如果你对它的外观感到困惑。
猜你喜欢
  • 2013-08-25
  • 1970-01-01
  • 2019-12-21
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2011-04-07
  • 1970-01-01
相关资源
最近更新 更多