3

我在基础库项目中定义了以下接口:

public interface IWorkContext {
    T User<T>() where T : IUser;

    // Note this method is kind of a shortcut so i don't
    // have to keep passing in T
    IUser User();
}

public interface IUser {
    int Id { get; }
    string UserName { get; }
}

现在我有另一个项目,它使用以下类(实现 IUser)引用上面的项目。

public class User : IUser {
   public virtual int Id { get; set; }
   public virtual string UserName { get; set; }
   // ... Code removed for brevity
}

现在我还需要实现 IWorkContext。这是我的第一次尝试:

public class DefaultWorkContext : IWorkContext {
    private readonly IUsersService _usersService;

    public DefaultWorkContext(IUsersService usersService) {
        _usersService = usersService;
    }

    public T User<T>() where T : IUser {
        return _usersService.GetUser<T>(1));
    }

    public User User() {
        return User<User>();
    }
}

然而,这给出了错误:

类型“T”不能用作泛型类型或方法“...GetUser(int)”中的类型参数“T”。没有从“T”到“用户”的装箱转换或类型参数转换。

我确定我做错了一些基本的事情。我很感激有关此模型的任何建议都可以改进。谢谢

编辑(根据要求,这里是 GetUser 方法):

public T GetUser<T>(int id) where T : User {
    return _session.Get<T>(id);
}

注意:_session 是一个 NHibernate 会话。

4

1 回答 1

2

这里的问题是您将泛型类型作为类型参数传递给您的GetUser()方法,这可能不满足您的GetUser()方法接受的泛型类型的继承条件。

编译器确保作为参数传递的类型始终满足类型条件。实际上,您可以编写 a class NotUserthat implementsIUser而不是User. 然后可以使用类型参数调用User<T>()方法,这将导致使用不继承自.NotUserGetUser()User

您的GetUser()方法只接受继承自的类型User

您需要更改GetUser()原型以接受实现的泛型类型,IUser或者更改原型以User<T>仅接受继承自的泛型类型User

要么:

public T GetUser<T>(int id) where T : IUser {
    return _session.Get<T>(id);
}

或这个:

public T User<T>() where T : User {
    return _usersService.GetUser<T>(1));
}

编辑: 你应该选择第一种还是第二种方法取决于你想要做什么。

1)您希望您IWorkContext使用IUser界面,并且您接受该GetUser()方法返回 a IUser=> pick option 1

2)您希望该GetUser()方法采用继承自的类型User,并且您接受该IWorkContext接口使用User而不是IUser=> 选择选项 2,并修改该IWorkContext接口。

对我来说,选项 1) 更好,因为您不需要修改界面并且不会破坏通用性。但这取决于你想要做什么。

于 2012-09-11T16:08:07.450 回答