Как вызывать методы с одинаковыми именами, но в разных, не связанных между собой классах? - PullRequest
0 голосов
/ 03 октября 2019

Я пишу c # скрипт в Unity

public class something1 : MonoBehaviour
{
    public void Dosomething(){

    }
}

public class something2 : MonoBehaviour
{
    public void Dosomething(){

    }
}

public class callingDoSometing
{
    public void callALLDosomething(){
        something1 s1 = new something1();
        something2 s2 = new something2();
        something3 s3 = new something3();
        something4 s4 = new something4();
        .
        .
        .
        s1.Dosomething();
        s2.Dosomething();
        s3.Dosomething();
        s4.Dosomething();
        .
        .
        .
    }
}

Мне нужно вызывать методы с одинаковыми именами (здесь Dosomething()) из разных классов. На самом деле мне нужно что-то вроде множественного наследования в других языках ООП, и я не хочу создавать дополнительные языки.

Ответы [ 3 ]

3 голосов
/ 03 октября 2019

Как правило, вы делаете это в C #, чтобы объявить интерфейс;Вы можете реализовать произвольно много интерфейсов, но расширить только один базовый тип.

interface IDoSomething
{
  void DoSomething();
}
public class Thing1 : SomeBaseClass, IDoSomething
{
    public void DoSomething(){ }
}
public class Thing2 : SomeBaseClass, IDoSomething
{
    public void DoSomething() { }
}

И теперь вы можете использовать IDoSomething как тип:

IDoSomething i1 = new Thing1();
IDoSomething i2 = new Thing2();
i1.DoSomething();
i2.DoSomething();
2 голосов
/ 03 октября 2019

Обычно это достигается с помощью интерфейсов.

public interface IDoSomething
{
    void Dosomething();
}
public class something1 : MonoBehaviour, IDoSomething
{
    public void Dosomething() { }
}
public class something2 : MonoBehaviour, IDoSomething
{
    public void Dosomething() { }
}

Если вы пытаетесь динамически обнаружить эти классы, вы должны сделать что-то вроде этого:

public class CallingDoSomething
{
    private Type[] Get_IDoSomethingTypes()
    {
        var allTypes = typeof(CallingDoSomething).Assembly.GetTypes();
        var searchFor = typeof(IDoSomething);

        return allTypes.Where(x => searchFor.IsAssignableFrom(x))
                       .Where(x => x.IsClass)
                       .ToArray();
    }
    public void CallAllSomethings()
    {
        var types = Get_IDoSomethingTypes();
        foreach (var type in types)
        {
            var instance = (IDoSomething)Activator.CreateInstance(type);
            instance.Dosomething();
        }
    }
}

Если у вас уже естьЕсли эти классы созданы, вы всегда будете обращаться с ними как с объектами IDoSomething:

public class CallingDoSomething
{
    private List<IDoSomething> m_somethingDoers = new List<IDoSomething>();
    public void OtherCodeThatPopulatedSomethingDoers()
    {
        // ...
    }

    public void CallAllSomethings()
    {
        foreach (var s in m_somethingDoers)
            s.Dosomething();
    }
}
1 голос
/ 03 октября 2019

Тот факт, что вы хотите сделать это с двумя MonoBehaviours, у которых нет другого родителя, может указывать на сомнительную разработку, но это можно сделать точно, используя GameObject.SendMessage.

public class something1 : MonoBehaviour
{
    public void Dosomething(){

    }
}

public class something2 : MonoBehaviour
{
    public void Dosomething(){

    }
}

public class callingDoSometing
{
    public void callALLDosomething(){
        GameObject g1 = new GameObject();
        g1.AddComponent<something1>();

        GameObject g2 = new GameObject();
        g2.AddComponent<something1>();

        GameObject g3 = new GameObject();
        g3.AddComponent<something2>();

        GameObject g4 = new GameObject();
        g4.AddComponent<something2>();


        ...

        g1.SendMessage("Dosomething"); 
        g2.SendMessage("Dosomething"); 
        g3.SendMessage("Dosomething"); 
        g4.SendMessage("Dosomething"); 
    }
}

Просто имейте в виду, что выполнение этого вызовет Dosomething для каждого MonoBehaviour на этом игровом объекте.

Если вы хотите точно указать, к какому MonoBehaviour позвонить и / илиесть ссылки на MonoBehaviour с, в частности, вы можете использовать MonoBehaviour.Invoke:

public class something1 : MonoBehaviour
{
    public void Dosomething(){

    }
}

public class something2 : MonoBehaviour
{
    public void Dosomething(){

    }
}

public class callingDoSometing
{
    public void callALLDosomething(){
        GameObject g1 = new GameObject();
        MonoBehaviour m1 = g1.AddComponent<something1>();

        GameObject g2 = new GameObject();
        MonoBehaviour m2 = g2.AddComponent<something1>();

        GameObject g3 = new GameObject();
        MonoBehaviour m3 = g3.AddComponent<something2>();

        GameObject g4 = new GameObject();
        MonoBehaviour m4 = g4.AddComponent<something2>();


        ...

        m1.Invoke("Dosomething",0f);
        m2.Invoke("Dosomething",0f);
        m3.Invoke("Dosomething",0f);
        m4.Invoke("Dosomething",0f);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...