如何在C#中使用自动后期绑定?

时间:2017-06-23 06:34:10

标签: c# class late-binding

请在我的代码中获取战利品:

public class TweenerBase {
    public void Update() {}
}

public class Vector3Tweener : TweenerBase {
    public void Update() { ... }
}

public class ColorTweener : TweenerBase {
    public void Update() { ... }
}

在另一个课程中我打电话:

private List < TweenerBase > tweens;

tweens = new List < TweenerBase > ();

ColorTweener tween1 = new ColorTweener();
Vector3Tweener tween2 = new Vector3Tweener();

tweens.Add( tween1 );
tweens.Add( tween2 );

我打电话时出现问题:

tweens[ 0 ].Update();

它调用:TweenerBase.Update()不是我预期的ColorTweener.Update()。我可以用这样的东西来解决它:

if ( tweens[ 0 ].type == "ColorTween" ) ( (ColorTween) tweens[ 0 ] ).Update();

但如果我使用类似的东西,这是非常不方便的解决方案:

( (ColorTween) tweens[ 0 ] ).Update();
float value = ( (ColorTween) tweens[ 0 ] ).GetCurrentValue();
( (ColorTween) tweens[ 0 ] ).SomeAnotherVoid();
( (ColorTween) tweens[ 0 ] ).SomeAnotherVoid2();

它看起来不可思议:)有没有办法让后期绑定只调用:

tweens[ 0 ].Update();

它会自动调用ColorTweener.Update()吗?

4 个答案:

答案 0 :(得分:1)

你需要在基类方法上使用virtual并在子类上覆盖它,目前你在子类方法上隐式使用new,所以在传递基类时调用update会调用base类方法。

答案 1 :(得分:1)

为什么没有将Update()函数设为虚拟?

答案 2 :(得分:0)

如果希望派生类的方法隐藏base的方法,则必须在派生类的方法声明中使用new关键字:

class derived : base
{
    public new void method() { }
}

或者,如果基类只是一个容器,您可以通过该容器一次操作不同的子类,您可以在基础中将该方法声明为abstract,通过覆盖派生的方法来提供它的实现。 / p>

abstract class base
{ 
    public abstract void method();
}

class derived : base
{
    public override void method()
    { // your code }
}

答案 3 :(得分:0)

您应该在基类中使用virtual关键字,并在派生类中使用override关键字,以便按预期工作。

using System;
using System.Collections.Generic;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var tweens = new List<TweenerBase>();

            var tween0 = new TweenerBase();
            var tween1 = new ColorTweener();
            var tween2 = new Vector3Tweener();

            tweens.Add(tween0);
            tweens.Add(tween1);
            tweens.Add(tween2);

            foreach (var tween in tweens)
            {
                tween.Update();
            }
        }
    }

    public class TweenerBase
    {
        /// <summary>
        /// Make sure you mark the base implementation as 'virtual'.
        /// </summary>
        public virtual void Update()
        {
            Console.WriteLine(nameof(TweenerBase));
        }
    }

    public class Vector3Tweener : TweenerBase
    {
        /// <summary>
        /// Make sure to user 'override' keyword to override the base implementation.
        /// </summary>
        public override void Update()
        {
            Console.WriteLine(nameof(Vector3Tweener));
        }
    }

    public class ColorTweener : TweenerBase
    {
        /// <summary>
        /// Make sure to user 'override' keyword to override the base implementation.
        /// </summary>
        public override void Update()
        {
            Console.WriteLine(nameof(ColorTweener));
        }
    }
}

此程序打印出来:

TweenerBase
ColorTweener
Vector3Tweener