Как я отправляю методу на основе типа выполнения параметра в C# <4?

У меня есть объект o который гарантируемый во времени выполнения быть одним из трех типов A, B, или C, все из которых реализуют единый интерфейс I. Я могу управлять I, но нет A, B, или C. (Таким образом я мог использовать пустой интерфейс маркера или так или иначе использовать в своих интересах общие черты в типах при помощи интерфейса, но я не могу добавить новые методы или изменить существующие в типах.)

У меня также есть ряд методов MethodA, MethodB, и MethodC. Тип выполнения o ищется и затем привык в качестве параметра к этим методам.

public void MethodA(A a) { ... }
public void MethodB(B b) { ... }
public void MethodC(C c) { ... }

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

public void Method(A a) { ... } // these are all overloads of each other
public void Method(B b) { ... }
public void Method(C c) { ... }

Теперь я позволяю C# сделать отправку вместо того, чтобы делать его вручную сам. Это может быть сделано? Наивный простой подход не работает, конечно:

Не может разрешить метод 'Метод (объект)'. Кандидаты:

  • освободите Метод (A)
  • освободите Метод (B)
  • освободите Метод (C)
5
задан Evan Barkley 12 May 2010 в 12:01
поделиться

5 ответов

Как насчет этого?

private Dictionary<Type, Action<I>> _mapping = new Dictionary<Type, Action<I>>
{ 
  { typeof(A), i => MethodA(i as A)},
  { typeof(B), i => MethodB(i as B)},
  { typeof(C), i => MethodC(i as C)},
};

private void ExecuteBasedOnType(object value)
{
    if(_mapping.ContainsKey(value.GetType()))
       _mapping(value.GetType())(value as I);
}
5
ответ дан 13 December 2019 в 05:31
поделиться

Если вы можете рефакторить это, переместите метод в интерфейс и каждый класс имеет свою реализацию:

I i = o as I;
i.Method();
7
ответ дан 13 December 2019 в 05:31
поделиться

Если 3 класса A, B и C реализуют интерфейс I, вам ничего не следует делать. Среда выполнения выбирает для вас правильный метод:

A a = new A();
class.Method(a); // will calll Method(A a)

B b = new B();
class.Method(b); // will call Method(B b)
0
ответ дан 13 December 2019 в 05:31
поделиться

Я не уверен на 100%, будет ли это работать в вашем сценарии, но похоже, что вы можете использовать частичные классы:

public interface IMethodCallable
{
    public void Method();
}

public partial class A : IMethodCallable
{
    public void Method()
    {
        ....
    }
}

затем для использования:

object o = getObject(); // we know this is A, B or C
((IMethodCallable)o).Method();
0
ответ дан 13 December 2019 в 05:31
поделиться

Предположительно O объявлен как тип / интерфейс, который я затем создал как b или c. Способ сделать это - иметь один общедоступный метод, который принимает параметр типа I, а затем выполняет свою логику в этом методе, например. вызовите частный метод AB или C.

Читая отредактированный пост, o относится к типу object, не забывайте четко понимать, когда вы говорите об объекте, потому что это не только тип c #, но и общий термин oop для экземпляра объекта класс.

Почему вы объявляете его как объект, а не как i, может это будет что-то еще позже?

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

if (o.GetType() == typeof(a))
{
   oa = (a)o;
   Method(oa);
}
else if(o.GetType() == typeof(b))
{
    ...
}

И т. Д.

В качестве альтернативы, если вы заставите метод принимать параметр типа i, вы можете сделать что-то вроде:

i oi = (i)o;
Method(oi);

Но вам все равно нужно будет сделать что-то вроде первого примера в вашем общедоступном методе.

0
ответ дан 13 December 2019 в 05:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: