C#接口<t> {T Func <t>(T t);}:具有通用返回类型的参数化方法的通用接口</t> </t>

时间:2009-10-26 20:50:28

标签: c# generics

我以为我会使用一些(我认为是)简单的泛型来在某些业务类上强制执行CRUD。 例如。

public interface IReadable <T>
{
    T Read<T>(string ID);
}

然后也许,我可以让NoteAdapter用Note类来做 R UD,例如。

public class NoteAdapter : IReadable<Note>
{
    public Note Read<Note>(string ID) {
        return new Note();
    }
}

但是出于某种原因,如果我同时使用泛型返回类型和使用相同泛型类型参数化的函数,那么编译器会变得混乱。也就是说,如果我这样做:

public interface IReadable <T>
{
    void Read<T>(string ID);
}
public class NoteAdapter : IReadable<Note>
{
    public void Read<Note>(string ID) {
        return new Note();
    }
}

它编译得很好,虽然它没有做我想要的! 另外,这个:

public interface IReadable <T>
{
    T Read (string ID);
}
public class NoteAdapter : IReadable<Note>
{
    public Note Read(string ID) {
        return new Note();
    }
}

工作正常,虽然它也不满足要求! - 为什么? 因为那时我不能有一个实现一堆这些接口的类......例如。

public interface IReadable <T>{
    T Read (string ID);
}
public class UniversalAdapter : IReadable<Note>, IReadable<Customer> ...
{
    public Note Read(string ID) {
        return new Note();
    }
    public Customer Read(string ID) {
        return new Customer();
    }
}

因为返回类型不是方法签名的一部分所以不会编译!

我的印象是,在C#3.5 +

T Foo(T t);
T Foo<T> (T t);
T Foo(<SomeType> someInstance);

所有人都有不同的签名!我在这里错过了什么?

3 个答案:

答案 0 :(得分:12)

您已经过度指定了界面。您在接口定义中声明T,但在方法的定义中重新声明

public interface IReadable <T>  /* T is declared here */
{
    T Read<T>(string ID); /* here, you've declare a NEW generic type parameter */
                          /* that makes this T not the same as the T in IReadable */
}

由于这种混淆,当您尝试实现接口时,最终会出现错误。

public class NoteAdapter : IReadable<Note> /* IReadable defines T to be Note */
{
    public Note Read<Note>(string ID) { /* Here, you're declaring a generic parameter */
                                        /* named Note.  This name then conflicts with */
                                        /* the existing type name Note */
        return new Note();
    }
}

要解决此问题,您只需要在界面和Read类中的NoteAdapter函数中删除泛型参数:

public interface IReadable <T>
{
    T Read(string ID);
}
public class NoteAdapter : IReadable<Note>
{
    public Note Read(string ID) {
        return new Note();
    }
}

修改

好的,我读了你的其他帖子,似乎你已经发现这个“有效”,但你似乎认为这是不正确的。为什么?这不符合什么要求?

答案 1 :(得分:3)

public interface IReadable <T> { T Read<T>(string ID); }

这里有两个不同的Ts:IReadable <T> and T Read<T>(string ID)

也许只是

public interface IReadable <T> { T Read(string ID); }

因为否则等于

public interface IReadable <T> { X Read<X>(string ID); }

Good Generics tutorial

编辑:

您可能需要public interface IReadable <T> { T Read(T ID); }吗?

答案 2 :(得分:2)

CIL does not support方法按返回类型重载。