[英]C# Using generics and interface implementation
Context: .NET 4.0, C# 上下文:.NET 4.0,C#
I'm creating a set of interfaces and a set of clases that implement them to provide some service. 我正在创建一组接口和一组实现它们以提供某些服务的clases。 The clients use the concrete clases but call methods that are declared using the interfaces as parameter types.
客户端使用具体的clases,但调用使用interfaces作为参数类型声明的方法。
A simplified example is this one: 一个简化的例子就是这个:
namespace TestGenerics
{
// Interface, of fields
interface IField
{
}
// Interface: Forms (contains fields)
interface IForm<T> where T : IField
{
}
// CONCRETE CLASES
class Field : IField
{
}
class Form <T> : IForm<T> where T : IField
{
}
// TEST PROGRAM
class Program
{
// THIS IS THE SIGNATURE OF THE METHOD I WANT TO CALL
// parameters are causing the error.
public static void TestMethod(IForm<IField> form)
{
int i = 1;
i = i * 5;
}
static void Main(string[] args)
{
Form<Field> b = new Form<Field>();
Program.TestMethod(b);
}
}
}
The code makes sense to me, but I get the compiler error: 代码对我有意义,但我得到编译器错误:
Argument 1: cannot convert from '
TestGenerics.Form<TestGenerics.Field>
' to 'TestGenerics.IForm<TestGenerics.IField>
' TestGenerics参数1:无法从'
TestGenerics.Form<TestGenerics.Field>
'转换为'TestGenerics.IForm<TestGenerics.IField>
'TestGenerics
I'm not sure what I'm doing wrong, I've read lots of pages on the internet but none solved my problem. 我不确定我做错了什么,我在互联网上阅读了很多页面,但没有解决我的问题。
Is there a solution that would not modify that much the architecture of what I'm trying to build: 是否有一个解决方案不会修改我正在尝试构建的架构:
Edit:I designed the interfaces in a way such that they should be independent of concrete clases that implement them. 编辑:我设计接口的方式使它们应该独立于实现它们的具体条款。 The concrete clases could be loaded from a dll, but most of the application Works with the interfaces.
具体的clases可以从一个DLL加载,但大多数应用程序与接口一起使用。 In some cases I need to use concrete clases, specially when using clases that need to be serialized.
在某些情况下,我需要使用具体的clases,特别是在使用需要序列化的clases时。
Thanks in advance. 提前致谢。
Alejandro 亚历杭德罗
The problem is that Form<Field>
implements IForm<Field>
but not IForm<IField>
. 问题是
Form<Field>
实现IForm<Field>
而不是IForm<IField>
。 You cannot use an inherited class (or interface) as a generic parameter unless it is marked as covariant with the out
identifier. 除非将其标记为与
out
标识符的协变,否则不能将继承的类(或接口)用作通用参数。 However, marking your interface as covariant will restrict the usage significantly (basically making in an "output-only" interface like IEnumerable
) so it may not work for you. 但是,将您的界面标记为协变将显着限制使用(基本上是在“仅输出”界面,如
IEnumerable
),因此它可能不适合您。
One way to get it to work is to make TestMethod
generic as well: 让它工作的一种方法是使
TestMethod
通用的:
public static void TestMethod<T>(IForm<T> form) where T:IField
{
int i = 1;
i = i * 5;
}
Others have pointed out the reasoning behind the error message, but let's examine the design of your sample code for a moment. 其他人已经指出了错误消息背后的原因,但让我们暂时检查一下示例代码的设计。 Perhaps you're using a generic where none is needed.
也许你正在使用一个不需要的通用。
You've already said you're using methods declared in the IField interface, so there may be no need to make your IForm class generic - simply have it store references to IField, instead of the generic argument 'T' (which is already guaranteed to be an IField anyway). 你已经说过你正在使用IField接口中声明的方法,所以可能没有必要让你的IForm类通用 - 只需要存储对IField的引用,而不是通用参数'T'(已经保证)无论如何要成为IField)。
For instance, use: 例如,使用:
public interface IForm
{
IEnumerable<IField> Fields { get; set; }
}
instead of 代替
public interface IForm<T> where T : IField
{
IEnumerable<T> Fields { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.