Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

276
Vistas
Convierta el tipo abstracto a 7 otros tipos posibles

Tengo la siguiente clase abstracta:

 public abstract partial class AsyncResult { }

Y otras 7 clases que heredan de él (aquí hay solo 2 como referencia):

 public partial class AsyncSearchResult : AsyncResult { private SearchResult searchResultField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:core_2020_2.platform.webservices.netsuite.com", Order=0)] public SearchResult searchResult { get { return this.searchResultField; } set { this.searchResultField = value; } } } public partial class AsyncGetListResult : AsyncResult { private ReadResponseList readResponseListField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(Order=0)] public ReadResponseList readResponseList { get { return this.readResponseListField; } set { this.readResponseListField = value; } } }

Tengo un método que devuelve el tipo abstracto y necesito convertirlo en uno de los tipos específicos para acceder a la propiedad deseada.

No puedo encontrar una manera de emitirlo en tiempo de compilación sin escribir 7 ifs para cada caso y duplicar mucho el código.

Agradezco cualquier tipo de ayuda.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Me gusta usar el patrón de visitante para esto:

 public interface IAsyncResultVisitor { void Accept(AsyncSearchResult searchResult); void Accept(AsyncGetListResult getListResult); // Etc... } public abstract partial class AsyncResult { public abstract void Visit(IAsyncResultVisitor visitor); } public partial class AsyncSearchResult : AsyncResult { // ... public override void Visit(IAsyncResultVisitor visitor) => visitor.Accept(this); }

Después:

 public class AsyncResultProcessor : IAsyncResultVisitor { public void ProcessAsyncResult(AsyncResult asyncResult) { asyncResult.Visit(this); } public void Accept(AsyncSearchResult searchResult) { // Access strongly-typed members of searchResult } public void Accept(AsyncGetListResult getListResult) { // Access strongly-typed members of getListResult } }

Tenga en cuenta que las declaraciones de cambio y las expresiones de cambio también ayudan aquí, aunque no garantizan que haya cubierto todos los casos (como lo hace el patrón de visitante):

 switch (asyncResult) { case AsyncSearchResult searchResult: // ... break; }
over 4 years ago · Santiago Trujillo Denunciar

0

Hubiera implementado el visitante de otra manera. El problema con la implementación de @ canton7 es que los datos tienen que saber cómo las personas deberían trabajar con ellos, ¡pero son solo datos simples!

Primero: AsyncResult debe tener un constructor private protected , por lo que ningún otro ensamblaje podría "implementar" esta clase abstracta

 public abstract class AsyncResult { private protected AsyncResult() {} } public sealed class ResultOne : AsyncResult() { public string Data { get; set; } } // 6 more to go

Hacer interfaz para que coincida con todos los tipos

 public interface IAsyncResultVisitor { void Visit(AsyncResult result); void VisitResultOne(ResultOne result); void VisitResultTwo(ResultTwo result); // 5 more to go }

Y cree un visitante predeterminado que tendrá propiedades para cada tipo que contenga una estrategia de visita

 public sealed class LambdaAsyncResultVisitor : IAsyncResultVisitor { public Action<ResultOne> OnVisitOne { get; set; } public void VisitResultOne(ResultOne result) { if (OnVisitOne is null) throw new InvalidOperationException("..."); OnVisitOne.Invoke(result); } // 6 more to go }

Esto nos permitiría usarlo de esta manera.

 AsyncResult result = ...; string someString = ""; new LambdaAsyncResultVisitor { OnVisitOne = r => someString = r.Data, OnVisitTwo = r => someString = "two", OnVisitThree => _ => throw new Exception("I know that is is impossible"), }.Visit(result); HandleSomeString(someString);

Esto brinda mucha más flexibilidad que el patrón de visitantes predeterminado.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda