C#/。NET 3.5:转换对象,扩展泛型列表 [英] C#/.NET 3.5: Casting objects that extend generic lists

查看:184
本文介绍了C#/。NET 3.5:转换对象,扩展泛型列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过与返回的接口类型的方法门面公开的API,而我遇到了一个问题,泛型列表和继承在C#/。NET 3.5。

I'm exposing an API through a facade with methods returning interface types, and I have run into an issue with generic lists and inheritance in C#/.NET 3.5.

我有两个接口:
IMyList(实现IList< IMyItem>)
IMyItem

I have two interfaces:
IMyList (implements IList<IMyItem>)
IMyItem

和三类:
MYLIST(实现IMyList,扩展了名单,其中,MyItem&GT;)
MyOtherList(实现IMyList,延伸的ObservableCollection&LT; MyItem&GT;)
MyItem(实现IMyItem)

And three classes:
MyList (implements IMyList, extends List<MyItem>)
MyOtherList (implements IMyList, extends ObservableCollection<MyItem>)
MyItem (implements IMyItem)

但它似乎并不可能。我应该如何去只露出什么是必要的,但仍然可以调用的方法正确的实现(也可能不同MYLIST和MyOtherList的实例)?

But it doesn't seem possible. How should I go about exposing only what is necessary, but still call the right implementations of the methods (that can vary for instance between MyList and MyOtherList)?

编辑:
我的门面是一家工厂看起来像这样:


My facade is a factory looking something like this:

public static class Facade {
    public static IMyList<IMyItem> CreateList() {
        return new MyList<MyItem>();
    }

    public static IMyItem CreateItem() {
        return new MyItem();
    }

    public static IConfiguration CreateConfiguration() {
        return new Configuration();
    }
} 

用法:

var list = Facade.CreateList();
list.DoSomethingOnChildren();

现在我期待DoSomethingOnChildren()实施 MYLIST 以一系列的 MyItem 对象执行。如果我是改变该方法返回的:

Now I'm expecting DoSomethingOnChildren() implemented in MyList to execute on a series of MyItem objects. If I was to change the method to return:

public static IMyList<IMyItem> CreateList() {
    return new MyOtherList<MyOtherItem>();
}

我希望DoSomethingOnChildren()的实施 MyOtherList 以一系列的执行 MyOtherItem 的对象。

I would expect DoSomethingOnChildren() implemented in MyOtherList to execute on a series of MyOtherItem objects.

推荐答案

仅仅因为 MyItem 工具 IMyItem 没有按'牛逼的意思 MYLIST&LT; MyItem&GT; 工具 IMyList&LT; IMyItem&GT; 。这么说吧,假设你有:

Just because MyItem implements IMyItem doesn't mean MyList<MyItem> implements IMyList<IMyItem>. Put it this way, assume you had:

IList<Shape> s = new List<Rectangle>();

如果这是允许的,它会导致吨的问题,因为这将让你这样做:

IF this were allowed, it would cause tons of problems because it would let you do:

s.Add(new Circle());

由于也是图形。一些通用接口的支持合作/禁忌变化,因为泛型类型参数仅在退出时尚,因为在的IList&LT; T&GT; 然而, T 参数在 code>和退出的位置,这使得它很难,和C#不支持它。

Since Circle is also a Shape. Some generic interfaces support co/contra-variance because the generic type parameter is used only in an in or out fashion, because in IList<T> however, the T argument is used both in in and out positions, this makes it difficult, and C# doesn't support it.

所以,你不能转换的参考,但你可以加载一个 MYLIST&LT的成员; MyItem&GT; IMyList&LT; IMyItem&GT; 通过其他手段(LINQ等),并返回列表的新实例

So, you can't convert the references, but you could load the members of an MyList<MyItem> into an IMyList<IMyItem> through other means (LINQ, etc) and return a new instance of the list.

如果你想支持两种接口,而且还允许特定的实施,可以使用显式接口实现。

If you wanted to support the two interface, but also allow a specific implementation, you could use explicit interface implementation.

更新

所以,如果你想要做类似的事情,你可以这样做,而不是。让你的界面返回了更通用的实现,然后让你的实现类有明确的实施只返回一个通用的实现,以及过载的具体实施。

So, if you want to do something similar, you could do this instead. Have your interface return back the more generic implementation, then have your implementing classes have an explicit implementation to return only a generic implementation, and an overload for the specific implementation.

所以是这样的:

// purely for illustrative purposes
public interface IShape { }
public class Rectangle : IShape { }

// represents your more "generic" interface
public interface ShapeMaker
{
    List<IShape> GetShapes();
}

// Your specific implementation
public class RectangleMaker : ShapeMaker
{
    // the explicit implementation of the interface satisfies the 
    // original, and behaves like original when called from an ShapeMaker 
    // interface reference
    List<IShape> ShapeMaker.GetShapes()
    {
        return new List<IShape>();
    }

    // but, we also provide an overload that returns a more specific version
    // when used with a reference to our subclass.  This gives us more 
    // functionality.
    public List<Rectangle> GetShapes()
    {
        return new List<Rectangle>();
    }
}

您只能这样做有显式接口实现的,因为你仍然必须满足原来的接口(必须具有相同的返回类型)。不过,这也让我们说,如果从子类引用中使用,它可以使用更具体的方法来代替。

You can only do this with explicit interface implementation, because you must still satisfy the original interface (must have same return type). But, it also allows us to say if used from the subclass reference, it can use the more specific method instead.

这篇关于C#/。NET 3.5:转换对象,扩展泛型列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆