继承对象的容器

时间:2016-05-20 16:44:44

标签: c# generics inheritance abstract

我有一个简单的类结构

var l = 74, t = 12; var k = 75, m = 14;
for (var i = 1; i < 10; i += 3) {
    for (var j = 0; j < 3; j++) {
        var x = i + j;
        $(".s" + x).css({
            "left": l + "px",
            "top": t + "px"
        });
        l -= 50;
        t += 50;
    }
    k += 50;
    m += 50;
    l = k;
    t = m;
}
var c = 1, d;
function wave() {
    m = 1;
    for (i = 1; i < 4; i++) {
        d = i;
        for (j = 1; j <= d; j++) {
            $(".s" + c).addClass("active");
            $(".s" + c).css({
                "animation-delay": c / 5 + "s"
            });
            alert(c);
            if (c != 1) {
                c += 2;
            }
        }
        m++;
        c = m;
    }
}
wave();

我确保abstract class A { List<A> containerList; ... } class B : A {....} class C : A {....} 只包含类containerListB的元素(因为列表填充在这些子类中,C是抽象的)。< / p>

现在,我想在某种程度上在A中拥有一个基本属性/方法,它将自己投射到对象的真实类型,即A或{{1} }。使用抽象方法很好,但获取B CCollection<T>个对象非常重要,因为我有依赖它的绑定。

3 个答案:

答案 0 :(得分:2)

  

现在,我想以某种方式在A中拥有一个基本属性/方法,它将自己投射到对象的真实类型,即B或C.

我认为您正在混合投射转换。 Cast是一个编译时构造,它只确定在编译时如何绑定方法和属性。它不会改变底层对象。

没有转换,因为该对象已经 BC - 因为{{1}是抽象的,你不能拥有实际上 A的对象。

因此,将基础集合作为AB的集合返回的方法只是:

Cs

如果您想要一个调用者确定类型的通用方法,您可以这样做:

public IEnumerable<B> GetBs()
{
    return containerList.OfType<B>();
}

public IEnumerable<C> GetCs()
{
    return containerList.OfType<C>();
}

答案 1 :(得分:2)

你可以使用这样的泛型(虽然看起来有点奇怪):

public abstract class A<T> where T : A<T>
{
    protected List<A<T>> containerList;
    public Collection<T> ContainerList
    {
        get { return new Collection<T>(containerList.OfType<T>().ToList()); }
    }
}

public class B : A<B>
{
   //...
}

public class C : A<C>
{
   //...
}

但是因为containerList应该只包含派生类型的元素,所以你可以使它完全通用:

protected List<T> containerList;

可以省略OfType()来电:

public Collection<T> ContainerList { get { return new Collection<T>(containerList); }}

一个缺点是有人可能有想法制作类D

public class D : A<B>
{}

现在会有一个D类,ContainerList类型为Collection<B>。但如果这就是他想要的......

答案 2 :(得分:0)

您可以使用is关键字(documentation link),而不是在列表中转换对象。如果您需要在列表上操作,请在执行操作之前询问if (containerList[i] is B)