Функция вызова C # на основе подтипа объекта - PullRequest
3 голосов
/ 15 июля 2009

Я смущен C # прямо сейчас.

У меня есть группа классов, скажем, A, B и C, которые все происходят от класса "Parent". У меня есть функция, которая принимает аргумент типа Parent, и в зависимости от того, с каким дочерним классом вызывается объект, с которым она вызывается, я хочу, чтобы она вызывала другой метод.

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

Проблема в том, что когда я нахожусь в функции, я знаю только, что она имеет тип Parent, и я могу использовать GetType, чтобы узнать, какой у меня дочерний класс, что позволило бы использовать словарь. В противном случае я бы, вероятно, использовал перегрузку функций.

Действительно, приведение типов является лучшим способом, позволяющим мне использовать перегрузку функций, которая была бы гораздо менее многословной, но я не знаю, как я мог бы это сделать или вообще это сработало бы.

Есть рекомендации?

Ответы [ 4 ]

7 голосов
/ 15 июля 2009

Все ли методы имеют одну и ту же сигнатуру? Если это так, сделайте его виртуальным (потенциально абстрактным) методом в родительском классе:

using System;

public abstract class Parent
{
    public abstract void DoSomething();
}

public class A : Parent
{
    public override void DoSomething()
    {
        Console.WriteLine("A.DoSomething()");
    }
}

public class B : Parent
{
    public override void DoSomething()
    {
        Console.WriteLine("B.DoSomething()");
    }
}

public class Test
{
    static void Main()
    {
        Parent a = new A();
        Parent b = new B();
        a.DoSomething();
        b.DoSomething();
    }
}

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

2 голосов
/ 15 июля 2009

Это похоже на идеальное использование для шаблона посетителя, если вы не можете добавить виртуальный метод в Parent и переопределить в A, B и C

1 голос
/ 15 июля 2009

Перегрузка - правильный путь

public void DoWork(Parent obj)
{
   if(obj is A)
     Foo((A)obj);

   else if(obj is B)
     Foo((B)obj);

   else
    Foo(obj);
}

public void Foo(Parent obj)
{
  //Do something for parent
}

public void Foo(A obj)
{
  //Do something for A
}

public void Foo(B obj)
{
  //Do something for B
}

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

Bar methodObject = new Bar();
MethodInfo method = methodObject.GetType().GetMethod(
            "Foo", new Type[] { obj.GetType()});

method.Invoke(methodObject, new object[]{obj});
0 голосов
/ 15 июля 2009

Отличается ли название метода? Или это другая реализация того же метода?

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

РЕДАКТИРОВАТЬ: с кодом ...

public abstract class parentClass
{
    //...other stuff...
    protected abstract void doSomething(); //or use virtual instead of abstract and give the method a body
}

public class childClass : parentClass
{
    //...other stuff...
    protected override void doSomething()
    {
       //...do something
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...