将子类转换为其通用祖父项

时间:2015-07-03 11:01:41

标签: c# generics c#-4.0

我发现自己处于这样一种情况:我需要提供与大约十二个不同但非常相似的对象执行相同任务的功能,所有这些对象都映射到我们数据库中的不同表。所以我认为这是一个很好的机会全力以赴继承和泛型。

我遇到了Grandparent - > Parent - > Child关系的问题,我需要能够将Child传递给一个期望Grandparent的函数,如果我不使用泛型,那就可以正常工作。我得到的错误是:

  

争论类型&#39; ChildA&#39;不能分配给参数类型&#39; GrandparentA<ParentB,ParentC>&#39;

下面是我正在尝试的一个非常简化的版本,但它仍然会抛出相同的错误:

void Main()
{
    var child = new ChildA();

    DoSomething(child);
}

public void DoSomething(GrandParentA<ParentB, ParentC> Data) { }

public abstract class GrandParentA<T1, T2> 
    where T1 : ParentB
    where T2 : ParentC
{
    public abstract T1 Foo { get; set; }
    public abstract T2 Bar { get; set; }
}

public abstract class ParentA<T> : GrandParentA<ChildB, T>
    where T : ParentC
{
    public override abstract ChildB Foo { get; set; }
    public override abstract T Bar { get; set; }
}

public class ChildA : ParentA<ChildC> 
{ 
    public override ChildB Foo { get; set; }
    public override ChildC Bar { get; set; }
}

public abstract class ParentB { }

public class ChildB : ParentB { }

public abstract class ParentC { }

public class ChildC : ParentC { }   

通过调用DoSomething(child)抛出了编译器错误,我原本认为这样可以正常工作,因为child的所有内容都可以向上覆盖祖父母的内容,没有任何向下转换来混淆事物(我想我在正确的方向上升/下降了!?)我哪里出错了?

1 个答案:

答案 0 :(得分:2)

类是不变的,因此GrandParentA<ParentB, ParentC>无法从GrandParentA<ChildB, ChildC>分配DoSomething。因此,您必须使GrandParentA方法成为通用方法,因此它可以接受public void DoSomething<T1, T2>(GrandParentA<T1, T2> Data) where T1 : ParentB where T2 : ParentC 任何通用参数:

Fragment sheet = getSupportFragmentManager().findFragmentByTag("frag");
FragmentTransaction ft =     getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.s    lide_up_info,0,0,R.anim.slide_down_info).show(sheet);
ft.addToBackStack("dialer");
ft.commit();

XML are:
slide_down_info.xml:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_longAnimTime"
    android:fromYDelta="0%p"
    android:toYDelta="100%p" />