关于c#:如何在类实例中调用常用函数?


How to call a common function in a class instance?

本问题已经有最佳答案,请猛点这里访问。

假设我有两个班:

1
2
3
4
5
6
7
8
9
10
11
class Batman
{
    public void Robin(){...}
    public void Jump(){...}
}

class Superman
{
    public void Kryptonie(){...}
    public void Jump(){...}
}

现在,我有了这些类的一个实例:

1
2
3
4
5
6
7
public object Crossover()
{
     var batman = new Batman();
     var superman = new Superman();

     return superman;
}

我不知道交叉将返回哪一类,可能是蝙蝠侠或超人。

1
2
3
4
var someVariableName = Crossover(); //I don't know if this contains an instance of Superman or Batman;

//I do know that no matter which class instance is returned, it will always contain a function named Jump which i want to trigger:
someVariableName.Jump();

现在我知道我可以做如下的事情:

1
2
3
4
if (someVariableName.GetType() == typeof(Superman))
{
    ((Superman) someVariableName).Jump()
}

但是,当我知道保存在该变量中的类的实例将始终包含跳转函数时,是否有一种方法可以在不必手动检查每种类型的情况下触发跳转函数?


使用接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface ISuperHero
{
    void Jump();
}

class Batman : ISuperHero
{
    public void Robin(){...}
    public void Jump(){...}
}

class Superman : ISuperHero
{
    public void Kryptonie(){...}
    public void Jump(){...}
}

然后从方法返回接口:

1
public ISuperHero Crossover()

这就是接口变得有用的地方。考虑这个接口:

1
2
3
4
public interface ISuperhero
{
    void Jump();
}

这些实现:

1
2
3
4
5
6
7
8
9
10
11
class Batman : ISuperhero
{
    public void Robin(){...}
    public void Jump(){...}
}

class Superman : ISuperhero
{
    public void Kryptonie(){...}
    public void Jump(){...}
}

它们是单独的实现,但它们共享一个通用的多态接口。然后,函数可以返回该接口:

1
2
3
4
5
6
7
public ISuperhero Crossover()
{
     var batman = new Batman();
     var superman = new Superman();

     return superman;
}

由于该接口有一个Jump()方法,因此可以直接调用它:

1
2
var someVariableName = Crossover();
someVariableName.Jump();


您可以创建一个定义方法的基类(或者一个接口,如果只是关于方法定义的话)。然后可以重写派生类中的实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
abstract class ActionFigure
{
    public abstract void Jump(); // just define it has a Jump method, but implement it in the deriving class

    public void SomethingGeneral()
    {
        // no need for an override, just implement it here
    }
}

class Batman : ActionFigure
{
    public void Robin(){...}
    public override void Jump(){...}
}

class Superman : ActionFigure
{
    public void Kryptonie(){...}
    public override void Jump(){...}
}