gpt4 book ai didi

c#-4.0 - 输入 : Binding an interface with a generic that is also an interface

转载 作者:行者123 更新时间:2023-12-02 22:30:19 24 4
gpt4 key购买 nike

我已经搜索过这个问题,但没有成功。我们开始吧。

假设我有一个接口(interface):

interface IQueryRepository<T> where T : class

我想绑定(bind)任何请求:

IQueryRepository<IClient>

到:

ConcreteQueryRepository<Client>

我已经尝试了显而易见的:

Bind<IGenericQueryRepository<IClient>>().To<ConcreteQueryRepository<Client>>()

但是我得到一个错误:

ConcreteQueryRepository<Client> cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T>.To<TImplementation>()' There is no implicit reference conversion from 'ConcreteQueryRepository<Client>' to 'IGenericQueryRepository<IClient>'

但我不明白为什么 GenericQueryRepository 实现了 IGenericQueryRepository 而 Client 实现了 IClient。

我希望 Ninject 给我一个具体的通用存储库,其中 T 是客户端。我希望这样可以避免在代码中使用具体类型。

可以吗?

最佳答案

这与 Covariance and Contravariance 有关.

在您的问题中,您提到了以下内容:

... GenericQueryRepository implements IGenericQueryRepository and Client implements IClient.

让我们使用 fruit 来简化它:Fruit 实现 IFruit。我们还将创建一个 Tree 类。

public interface IFruit { }
public class Fruit : IFruit { }
public class Tree<T> where T : IFruit { }

Tree<IFruit> tree = new Tree<Fruit>() // error

这将重现您遇到的相同类型的错误。为什么?简单。

尽管 Fruit 实现了 IFruit,但 Fruit Tree 并未实现 IFruit Tree。 Fruit Tree 和 IFruit Tree 之间不可能进行强制转换,尽管您可能会这样。它们都是树,但具有不同 类型参数。它们的类型参数彼此相关这一事实并不重要。

换句话说:Fruit Tree 和 IFruit Tree 之间不可能进行转换,因为它们的类型参数不匹配。

一般来说,当使用泛型进行转换时,确保它们的类型参数匹配。但是,也有一些异常(exception)情况。参见 Variance in Generic Interfaces .

在您的情况下,您可以通过使用 IClient 作为 GenericQueryRepository 类的类型参数来修复它。这样做将允许转换,因为类型参数匹配。但我不知道您的应用程序架构,因此此修复可能不适用于您的情况。


编辑:为了更容易理解,复制粘贴下面的代码,看看编译器说了什么。

interface IFruit { }
class Fruit : IFruit { }
interface ITree<T> where T : IFruit { }
class Tree<T> : ITree<T> where T : IFruit { }

class Program
{
static void Main(string[] args)
{
ITree<Fruit> test1 = new Tree<Fruit>(); // compiles: type parameters match
ITree<IFruit> test2 = new Tree<Fruit>(); // fails: type parameters don't match
ITree<Fruit> test3 = new Tree<IFruit>(); // fails: type parameters don't match
ITree<IFruit> test4 = new Tree<IFruit>(); // compiles: type parameters match

IEnumerable<IFruit> test5 = new List<Fruit>(); // compiles: this is one of the exceptional cases
}
}

这应该清楚什么是可能的,什么是不可能的。

关于c#-4.0 - 输入 : Binding an interface with a generic that is also an interface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12388066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com