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

IM.*_*IM. 9 c# generics

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

public interface IReadable <T>
{
    T Read<T>(string ID);
}
Run Code Online (Sandbox Code Playgroud)

然后也许,我可以用NoteAdapter 用Note类做C R UD,例如.

public class NoteAdapter : IReadable<Note>
{
    public Note Read<Note>(string ID) {
        return new Note();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我在C#3.5 +的印象中

T Foo(T t);
T Foo<T> (T t);
T Foo(<SomeType> someInstance);
Run Code Online (Sandbox Code Playgroud)

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

P D*_*ddy 14

你已经过度指定了界面.您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 */
}
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

要解决这个问题,您只需要Read在接口和NoteAdapter类中从函数中删除泛型参数:

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

编辑:

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