tipos - pasar objetos como parametros en c#
¿Cómo envío a un método basado en el tipo de tiempo de ejecución de un parámetro en C#<4? (5)
Tengo un objeto o
que garantizado en tiempo de ejecución para ser uno de los tres tipos A
, B
o C
, todos los cuales implementan una interfaz común I
Puedo controlar I
, pero no A
, B
o C
(Por lo tanto, podría utilizar una interfaz de marcador vacía, o de alguna manera aprovechar las similitudes en los tipos mediante el uso de la interfaz, pero no puedo agregar nuevos métodos o cambiar los existentes en los tipos).
También tengo una serie de métodos MethodA
, MethodB
y MethodC
. El tipo de tiempo de ejecución de o
se busca y luego se usa como un parámetro para estos métodos.
public void MethodA(A a) { ... }
public void MethodB(B b) { ... }
public void MethodC(C c) { ... }
Usando esta estrategia, en este momento se debe realizar un control en el tipo de o
para determinar qué método se debe invocar. En cambio, me gustaría simplemente tener tres métodos sobrecargados:
public void Method(A a) { ... } // these are all overloads of each other
public void Method(B b) { ... }
public void Method(C c) { ... }
Ahora voy a dejar que C # haga el despacho en lugar de hacerlo manualmente. Se puede hacer esto? El enfoque ingenuo y directo no funciona, por supuesto:
No se puede resolver el método ''Método (objeto)''. Los candidatos son:
- Método nulo (A)
- Método nulo (B)
- Método nulo (C)
¿Qué tal algo como esto?
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);
}
No estoy 100% seguro de si esto funcionará en tu escenario, pero parece que podrías usar clases parciales:
public interface IMethodCallable
{
public void Method();
}
public partial class A : IMethodCallable
{
public void Method()
{
....
}
}
luego para el uso:
object o = getObject(); // we know this is A, B or C
((IMethodCallable)o).Method();
Presumiblemente, O se declara como tipo / interfaz y luego se crea una instancia como ab o c. La forma de hacerlo sería tener un único método público: tomar un parámetro de tipo I y luego hacer su lógica dentro de ese método, por ejemplo, llamar al método privado AB o C.
Leyendo su publicación editada, o es de tipo objeto, recuerde que debe ser claro cuando toma sobre un objeto, además de ser ac # tipo, es un término genérico para una instancia de una clase.
¿Por qué lo declaras como un objeto, en lugar de una i, podría ser algo más tarde?
Si es así, para usar sus métodos sobrecargados, deberá destrabarlos antes de llamar al método. p.ej
if (o.GetType() == typeof(a))
{
oa = (a)o;
Method(oa);
}
else if(o.GetType() == typeof(b))
{
...
}
Etc.
Alternativamente, si hiciste el método toma un parámetro de tipo i, podrías hacer algo como:
i oi = (i)o;
Method(oi);
Pero aún tendría que hacer algo como el primer ejemplo dentro de su método público.
Si las 3 clases A, B y C implementan la interfaz I, no debería hacer nada. Es el tiempo de ejecución el que elige el método adecuado para usted:
A a = new A();
class.Method(a); // will calll Method(A a)
B b = new B();
class.Method(b); // will call Method(B b)
Si puede refactorizar esto, mueva el método a la interfaz y haga que cada clase tenga su implementación:
I i = o as I;
i.Method();