Можно ли создать многоадресный делегат в C # 4.0 из некоторого набора имен методов? - PullRequest
4 голосов
/ 14 июня 2011

Я пишу простую игру на XNA, и у меня возникла проблема с делегатами. Я использую их для представления физики в игре, например ::1001

public delegate void PhysicsLaw(World world);

//for gravitation
static public void BallLawForGravity(World world)
        {
            if (world.ball.position.Y != world.zeroLevel)
                //v(t) = v0 + sqrt(c * (h - zeroLevel))
                world.ball.speed.Y += (float)Math.Sqrt(0.019 * (world.zeroLevel - world.ball.position.Y)); 
        }

И я хочу создать многоадресные делегаты для различных объектов / обстоятельств, состоящих из множества методов, таких как BallLawForGravity(), но я могу сделать это только так:

processingList = BallLawForBounce;
processingList += BallLawForAirFriction;
...
processingList += BallLawForGravity;

Очевидно, это не выглядит хорошо. Существует ли какой-либо стандартный способ создания многоадресного делегата из коллекции имен методов?

Ответы [ 2 ]

4 голосов
/ 14 июня 2011

Используйте статический метод Delegate.Combine Method (Delegate[]) для таких задач.

 PhysicsLaw[] delegates = new PhysicsLaw[] {
        new PhysicsLaw( PhysicsLaw ),
        new PhysicsLaw( BallLawForAirFriction )
    };

    PhysicsLaw chained = (PhysicsLaw) Delegate.Combine( delegates );
    chained(world);

Дополнительные примеры .

Обновление Для этого вы можете использовать создание делегата через Reflection , но я не рекомендую его, потому что это очень медленная техника.

2 голосов
/ 14 июня 2011

Допустим, вы объявили

    public delegate void foo(int x);
    public static void foo1(int x) { }
    public static void foo2(int x) { }
    public static void foo3(int x) { }

Теперь вы можете объединить их напрямую с Delegate.Combine, если вы не против набрать имя делегата дважды:

    foo multicast = (foo)Delegate.Combine(new foo[] { foo1, foo2, foo3 });

ИлиВы можете написать универсальную функцию для их объединения, если вы не против набрать имя делегата один раз:

    public static T Combine<T>(params T[] del) where T : class
    {
        return (T)(object)Delegate.Combine((Delegate[])(object[])del);
    }

    foo multicast2 = Combine<foo>(foo1, foo2, foo3);

Или вы можете написать неуниверсальную функцию для объединения их, если вы не хотите вводитьимя делегата вообще:

    public static foo Combine(params foo[] del)
    {
        return (foo)Delegate.Combine(del);
    }

    foo multicast3 = Combine(foo1, foo2, foo3);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...