Cambie la caja en el tipo c #

Posible duplicado:
C # – ¿Hay una mejor alternativa que esta para ‘encender el tipo’?

Hola, supongo que obtengo un gran if / else en el tipo de clase. ¿Hay alguna forma de hacerlo con una caja de interruptores?

Ejemplo:

function test(object obj) { if(obj is WebControl) { }else if(obj is TextBox) { } else if(obj is ComboBox) { } 

etc …

Me gustaría crear algo así como

 switch(obj) { case is TextBox: break; case is ComboBox: break; } 

}

No.

http://blogs.msdn.com/b/peterhal/archive/2005/07/05/435760.aspx

Recibimos muchas solicitudes de adiciones al lenguaje C # y hoy voy a hablar sobre uno de los más comunes: activar el tipo. El tipo de cambio parece una característica bastante útil y directa: agregue una construcción tipo interruptor que active el tipo de expresión, en lugar del valor. Esto podría verse más o menos así:

 switch typeof(e) { case int: ... break; case string: ... break; case double: ... break; default: ... break; } 

Este tipo de enunciado sería extremadamente útil para agregar un método virtual como el despacho sobre una jerarquía de tipos disjuntos, o sobre una jerarquía de tipos que contiene tipos que no le pertenecen. Al ver un ejemplo como este, puede concluir fácilmente que la característica sería directa y útil. Incluso podría hacerte pensar “¿Por qué esos diseñadores de idiomas # * y% $ perezosos C # me hacen la vida más fácil y añaden esta característica de lenguaje simple y que ahorra tiempo?”

Desafortunadamente, al igual que muchas características de lenguaje ‘simples’, el cambio de tipo no es tan simple como parece. Los problemas comienzan cuando observa un ejemplo más significativo, y no menos importante, como este:

 class C {} interface I {} class D : C, I {} switch typeof(e) { case C: … break; case I: … break; default: … break; } 

Enlace: https://blogs.msdn.microsoft.com/peterhal/2005/07/05/many-questions-switch-on-type/

El siguiente código funciona más o menos como uno esperaría un cambio de tipo que solo mira el tipo real (por ejemplo, qué devuelve GetType() ).

 public static void TestTypeSwitch() { var ts = new TypeSwitch() .Case((int x) => Console.WriteLine("int")) .Case((bool x) => Console.WriteLine("bool")) .Case((string x) => Console.WriteLine("string")); ts.Switch(42); ts.Switch(false); ts.Switch("hello"); } 

Aquí está la maquinaria requerida para hacerlo funcionar.

 public class TypeSwitch { Dictionary> matches = new Dictionary>(); public TypeSwitch Case(Action action) { matches.Add(typeof(T), (x) => action((T)x)); return this; } public void Switch(object x) { matches[x.GetType()](x); } } 

Sí, puedes activar el nombre …

 switch (obj.GetType().Name) { case "TextBox":... } 

Aquí hay una opción que sigue siendo cierta: podría cumplir con los requisitos del OP para poder activar el tipo. Si entrecierra los ojos lo suficiente, casi parece una verdadera statement de cambio.

El código de llamada se ve así:

 var @switch = this.Switch(new [] { this.Case(x => { /* WebControl code here */ }), this.Case(x => { /* TextBox code here */ }), this.Case(x => { /* ComboBox code here */ }), }); @switch(obj); 

La x en cada lambda anterior está fuertemente tipada. No se requiere lanzamiento.

Y para hacer que esta magia funcione, necesitas estos dos métodos:

 private Action Switch(params Func[] tests) { return o => { var @case = tests .Select(f => f(o)) .FirstOrDefault(a => a != null); if (@case != null) { @case(); } }; } private Func Case(Action action) { return o => o is T ? (Action)(() => action((T)o)) : (Action)null; } 

Casi trae lágrimas a tus ojos, ¿verdad?

Sin embargo, funciona. Disfrutar.

Lo más simple que se puede hacer es usar dinámica, es decir, definir los métodos simples como en la respuesta de Yuval Peled:

 void Test(WebControl c) { ... } void Test(ComboBox c) { ... } 

Entonces no puede llamar directamente a Prueba (obj), porque la resolución de sobrecarga se realiza en tiempo de comstackción. Debe asignar su objeto a una dinámica y luego llamar al método de prueba:

 dynamic dynObj = obj; Test(dynObj);