C#: вызов заранее неизвестного метода

0000

Допустим есть класс

class A
{
public void method1 {...}
public void method2 {...}
}

Можно ли в C# сделать что-то типа такого?

A a = new A;
int i = 2;
f(a."method"+i);

php аналог - call_user_func

Alexander08

dynamic.
хотя давай поподробнее что нужно в итоге?

Alexander08

ну и в твоем случае вроде можно просто if-ом обойтись

0000

Про dynamic можно капельку подробнее?
if не хочется - очень большой case получится.

zorin29

Либо Reflection, либо динамический тип.

Alexander08

обойдись case или if если в твоем случае это возможно.
динамики и рефлекшины гораздо более затратны и юзаются в совсем крайних случаях.

0000

Обошелся, добавив абстрактный класс, от которого буду наследовать классы.
Вместо case буду делать так

public abstract class Behaviour : MonoBehaviour {
public abstract void Do(int Action);
}
...
Behaviour c = this.GetComponent(this.name + "Behaviour") as Behaviour; // поскольку исходники позволяют искать дополнительный компонент по строке
if (c != null)
c.Do(5);

P.S. Это шкодинг в Unity :)

Alexander08

больно бил бы за такой стиль. но тебе виднее. ты ведь так и не сказал что в итоге тебе нужно?

0000

, что не так со стилем?
Как смог, так и сказал. Ожидать, что здесь кто-то знает Unity или описывать, как и что там делает, а потом спрашивать, несколько странно.
Да и думал, может есть штатная возможность это выполнять, как в том же php.

zorin29

Ну нужен, видимо, какой-то Inversion of Control, и выбрана не самая ужасная из его топорных реализаций.
2 : "Настоящий программист может писать на Фортране на любом языке". Твое решение приемлемо, но на сишарпе "принято" писать по-другому.

hov77



// если нужно бросить исключение если метод не найден
a.GetType.GetMethod(string.Format("method{0}", i .Invoke(a, null);


// если исключение бросать не нужно
System.Reflection.MethodInfo m;
if ( ( m = a.GetType.GetMethod(string.Format("method{0}",i != null)
m.Invoke(a, null);

// Если нужно часто использовать

public static class MyExtensions
{
public static InvokeMethod( this object a, string name, object[] param = null )
{
if ( a == null )
return;

System.Reflection.MethodInfo m;
if ( ( m = a.GetType.GetMethod(name != null)
m.Invoke(a, param);
}
}
...
в коде

a.InvokeMethod( "method1");
a.InvokeMethod( "method2");
a.InvokeMethod( "method3");

state7401281

попробуй reflection, но это может закончится восстанием машин

0000

Да все, уже не надо.
Сначала сделал через динамический вызов, как написал выше. Потом через наследование и переопределение родительского метода.

Vyacha

добавив абстрактный класс
Интерфейс же

murmashik

 
Обошелся, добавив абстрактный класс, от которого буду наследовать классы.
Вместо case буду делать так
code:
public abstract class Behaviour : MonoBehaviour {
    public abstract void Do(int Action);
}
...
Behaviour c = this.GetComponent(this.name + "Behaviour") as Behaviour; // поскольку исходники позволяют искать дополнительный компонент по строке
if (c != null)
     c.Do(5);
P.S. Это шкодинг в Unity

Будь готов, что через пару лет в твою карму будут активно поступать лучи поноса от того, кто будет поддерживать этот код...
А вообще это яркий пример того, как весьма разумный паттерн (IoC/DI) и фреймворк (Unity превращаются в глазах общественности в говно из-за того, что кто-то решил сделать "в С# также как и php".

0000

, написал же, что сделал уже через промежуточный класс и наследование. Код этот поддерживать никто не будет - это Unity, т.е. игровой движок.
Оставить комментарий
Имя или ник:
Комментарий: