使用通用方法实现接口

77

我对这个问题一无所知,似乎找不到我之前写的任何相关示例。我正在尝试使用类实现一个通用接口。当我实现该接口时,我认为某些事情出了问题,因为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;
}

那么我的课程应该长什么样子呢?


1
错误的问题标题。普通类和接口中有通用方法,还有带有方法的通用接口。 - Kobor42
3个回答

118
您应该重新设计您的界面,具体做法如下:
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
    }
}

太好了。我知道我必须指定通用变量,但是不记得在哪里(无恶意)。谢谢Reed! - Jason N. Gaylord
2
期望的结果可能不可能实现,但在我看来,这个答案并没有通用方法,而是一个具有依赖方法的通用类。从技术上讲,通用方法似乎会有自己的模板参数。 - Catskul
你是正确的。问题标题错误,但回答了问题。 - Kobor42
你可以使用 Activator 来创建 T 的实例,像这样:T obj = Activator.CreateInstance<T>(); - guogangj
@ReedCopsey,where T : class 中的 class 是否表示任意类?这个关键字通常用于创建类,那么为什么在这里使用它?为什么不写成 where T : object - Shuzheng
显示剩余2条评论

14
我认为您可能需要重新定义接口,像这样:
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<T, U>:IOurTemplate<T, U> -- 我不确定Jason想要哪个选项。 - Reed Copsey

2
-- 编辑 --
其他答案更好,但请注意,如果您不确定应该是什么样子,您可以让 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 想要的。 - ChrisW
1
我同意,我认为你的建议很好。我只是想展示一下,如果你对接口的实现方式感到困惑,可以让VS帮你实现接口。 - Noon Silk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接