使用基类而不进行明确的转换

时间:2016-06-30 08:51:11

标签: c# polymorphism

我有2个班级:

class MyBase() { }

class A : MyBase() { public int i;}

class B: MyBase() { public int i; }

我希望实现以下目标:

void f(MyBase myBase)
{
    if(myBase.GetType() == typeof(A))
    {
        myBase.i = 1;
    }
    else if (myBase.GetType() == typeof(B))
    {
        myBase.i = 2;
    }
} 

无需执行:

((A)myBase).i = 1;
((B)myBase).i = 2;

每次(当然,假设myBase的派生类总是包含i)。

有办法做到这一点吗?

4 个答案:

答案 0 :(得分:4)

如果您“假设MyBase的每个派生类都必须包含i”,则表明i属于MyBase。然后你的代码已经运行了:

public class MyBase
{
    public int i;
}

或者你想在子类中使它成为可覆盖的,你可以通过使基类和属性抽象来强制它:

public abstract class MyBase
{
   public abstract int i { get; }
}

public class A : MyBase
{
    public override int i 
    {
        get { return 1; }
    }
}

public class B : MyBase
{
    public override int i
    {
        get { return 2; }
    }
}

答案 1 :(得分:0)

f移动到派生类中。

abstract class MyBase()
{
    public abstract void f();
}

class A : MyBase() 
{ 
    public int i;

    public override void f()
    {
        i=1;
    }
}

class B: MyBase()
{ 
    public int i; 

    public override void f()
    {
        i=2;
    }
}

然后在你得到的任何实例上调用f ......

MyBase x = new A();
x.f(); // calls "i=1"
x = new B();
x.f(); // calls "i=2"

或者,如果您愿意,请保持接近原始语法:

void f(MyBase myBase)
{
    myBase.f(); // calls the one or the other depending on the actual type of myBase
} 

答案 2 :(得分:0)

  

当然,假设myBase的派生类总是包含   我

在这种情况下,更改类结构并将i移动到基类会更好。 至少在基类中定义一个抽象成员i,以便开发人员知道在派生类中实现它。

否则你会遇到一些问题,因为你忘了在你的派生类中实现i,这会破坏整个系统。

这样的问题很烦人,但是如果你在这里接受这种结构,你也会在其他地方这样做,你的课程将成为维护的噩梦。

答案 3 :(得分:-1)

在每个派生类的构造函数中设置i的值,而不是在外部,因为我似乎是一个取决于每个特殊类型的值。

class A : MyBase() {
public A(){ i = 1;} 
public int i;
}

class B: MyBase() { 
public B(){ i = 2;}
public int i; 
}