简体   繁体   English

如何将两个相似的具体对象传递给具有在C#中实现泛型的接口参数的方法?

[英]How do I pass two similar concrete objects to a method with interface parameters that implement generics in C#?

I have the following interface declarations: 我有以下接口声明:

interface IOrder<T> where T: IOrderItem
{
     IList<T> Items { get; set; }
}

interface IDistro<T> : IOrder<T> where T: IOrderItem
{

}

I have two concrete classes, like so: 我有两个具体的类,如下所示:

// DistroItem implements IOrderItem
public class Distro : IDistro<DistroItem>
{
    public IList<DistroItem> Items { get; set; }
}

// PerishableOrderItem implements IOrderItem
public class PerishableOrder : IDistro<PerishableOrderItem>
{       
    public IList<PerishableOrderItem> Items { get; set; }
}

Lastly, I have a static service method for saving to the database: 最后,我有一个用于保存到数据库的静态服务方法:

public static void UpdateDistro(IDistro<IOrderItem> distro)
{

}

My problem is, how do I pass a distro of either concrete type to my static method? 我的问题是,如何将两种具体类型的发行版传递给我的静态方法? The following doesn't compile: 以下内容无法编译:

Distro d = new Distro();
UpdateDistro(d);

The error is: 错误是:

The best overloaded method match for UpdateDistro(IDistro<IOrderItem>)' has some invalid arguments

Is contravariance the answer? 协方差是答案吗? I tried adding <in T> to the original interface declaration, but that added more errors that I was unable to resolve. 我尝试将<in T>添加到原始接口声明中,但这增加了我无法解决的更多错误。 This is my first in depth foray into interfaces and I'm sure generics is adding complexity, so there might be a fundamental lack of understanding here. 这是我第一次深入接口,我确信泛型会增加复杂性,因此这里可能根本缺乏理解。

Have you tried this: 您是否尝试过:

public static void UpdateDistro<T>(IDistro<T> distro) 
  where T : IOrderItem
{  
} 

EDIT: 编辑:

With empty implementations for DistroItem and PerishableItem classes (both implementing IOrderItem ), I've got the following compiling without an error: 使用DistroItemPerishableItem类的空实现(都实现IOrderItem ),可以进行以下编译而不会出现错误:

Distro d = new Distro();
PerishableOrder p = new PerishableOrder();

UpdateDistro(d);
UpdateDistro(p);

You can define a covariant generic parameter in your interface, you need to change the interface a little bit though to ensure that T is not uses contravariantly: 您可以在接口中定义协变泛型参数,尽管需要确保稍微改变接口,以确保T不反向使用:

public interface IOrder<out T> where T : IOrderItem
{
    IEnumerator<T> Items { get; }
}

public interface IDistro<out T> : IOrder<T> where T : IOrderItem
{

}

To define T as coverient parameter ( out ), allows for implicit conversion of classes that implement your variant interfaces. 要将T定义为Coverient参数( out ),允许对实现您的变体接口的类进行隐式转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM