Posible duplicado:
C # – ¿Hay una mejor alternativa que esta para ‘encender el tipo’?
El código heredado de mi compañía tiene algo como lo siguiente
public override Uri GetUri(object obj) { if ((obj is Entry) || (obj is EntryComment)) { // } if (obj is Blog) { // } // if obj is blah blah blah }
Este método es feo. Quiero refactorizarlo, pero no conozco una técnica para iterar sobre los tipos “posibles” que pueden ser obj.
¿Cómo puedo refactorizar esto?
Gracias.
También puede refactorizar esto con interfaces
public interface IHasUri { public Uri GetUri(); }
e implementa esta interfaz en toda tu jerarquía. De lo que puedes usar
public Uri GetUri(object obj) { IHasUri hasUri = obj as IHasUri; if(hasUri != null) Uri uri = hasUri.GetUri(); // bla bla bla }
Un par de opciones:
Si está utilizando C # 4, puede usar el tipado dynamic y dividir el método en varias sobrecargas:
public Uri GetUri(dynamic obj) { return GetUriImpl(obj); } private Uri GetUriImpl(Entry entry) { ... } private Uri GetUriImpl(EntryComment comment) { ... }
En este caso, es probable que desee algún tipo de método de “protección” en caso de que no sea un tipo conocido.
Puede crear un Dictionary
:
private static Dictionary> UriProviders = new Dictionary> { { typeof(Entry), value => ... }, { typeof(EntryComment), value => ... }, { typeof(Blog), value => ... }, };
y entonces:
public Uri GetUri(object obj) { Func
Tenga en cuenta que esto no cubrirá el caso en el que reciba un subtipo de Entry
etc.
Ninguno de estos es particularmente agradable, fíjate … Sospecho que un rediseño de nivel superior puede ser preferible.
Creo que Lasse V. Karlsen tiene el derecho en sus comentarios, un rediseño es más apropiado quizás
Podrías crear una interfaz como sugiere Stecya
public interface IUriAccessible { //or some sort of a more descriptive name Uri Url {get;} }
y luego, para cada objeto que le interese, por ejemplo, Entry
, podría
public class Entry:IUriAccessible { //... other code here public Uri Url { get { //return uri here } } }
y ahora puedes simplemente llamarlo al objeto
var entry = new Entry(); var uri = entry.Url;
Puede tener una List
con todos los tipos que desee verificar e iterar esa lista. pero no creo que eso haga que el código sea más rápido.
No se pueden switch-case
tipos de switch-case
.
Una expresión de interruptor o etiqueta de caso debe ser un bool, char, string, integral, enum o tipo anulable correspondiente