2010-06-03 12 views
5

Aquí hay una función típica que devuelve verdadero/falso;C# ¿Es posible tener un tipo de devolución genérico?

private static bool hasValue() 
{ 
    return true; 
} 

Ahora en un error, me gustaría volver a mi propio objeto de error personalizado con definición:

public class Failure 
    { 
     public string FailureDateTime { get; set; } 
     public string FailureReason { get; set; } 
    } 

lo que habría esperado que ser capaz de lanzar este objeto personalizado por ejemplo ...

private static bool hasValue() 
{ 
    try 
     { 
      ...do something 
     } 
    catch 
     { 
     throw new Failure(); 
     } 
    return true; 
} 

esto no es posible, y yo no quiero para derivar fracaso desde System.IO.Exception porque tengo personalmente tenido problemas de serialización excepciones en C# (Esto fue con .net v2).

¿Cuál es la mejor solución ideal para este problema? ¿Debo simplemente trabajar con un objeto estático privado? ¿O hay una manera más limpia de devolver un objeto personalizado o de omitir el tipo de devolución típico en caso de error (sin usar System.IO.Exception)?

No soy del todo salvaje con el uso de un objeto, porque entonces tengo que validar el resultado mediante el uso de casting y más booleano.

+0

Creo que lo único que se puede arrojar es algo que se deriva de Excepción. – kenny

Respuesta

10

Este tipo de solución puede ajustarse a este caso:

var exception = new Exception(); 
exception.Data.Add("Failure", new Failure()); 
throw exception; 

Usted puede lanzar la excepción (recomendado para definir su propio tipo de excepción), y utilizar el diccionario de datos para sostener el fracaso. En el código catch puede tomar los datos y serializarlos. Si crea su propio tipo de excepción, puede colocar el error en una propiedad.

Comentario: No lo verifiqué, pero ¿está seguro de que las excepciones no son serializables?

+1

+1 Eso es muy lindo. –

+0

Creo que implementaré esta solución, se ve muy prometedor. –

+0

He tenido algunos problemas al serializar excepciones en la práctica. –

7

No deseo derivar un error de System.IO.Exception debido a la imposibilidad de serializar una excepción en C#.

La suposición de que se basa en esta pregunta es que no puede serializar las excepciones derivadas de IOException. Sin embargo, deseo desafiar esta suposición. IOException está marcado como Serializable. Todo lo que tienes que hacer es marcar tu subclase como serializable también.

consulte la documentación de IOException:

[SerializableAttribute] 
[ComVisibleAttribute(true)] 
public class IOException : SystemException 
6

Necesitas derivar de System.Exception (o cualquier otra no sealed subclase de ella) si desea crear su propia clase de excepción. La falla en la serialización de la que está hablando probablemente sea el hecho de que no implementó el constructor de serialización.

Visual Studio tiene un fragmento de código que crea una plantilla recomendada para la excepción de subclases. Puede obtenerlo escribiendo exception y presionando , tab dos veces.

Esto es lo que sale:

[Serializable] 
public class MyException : Exception { 
    public MyException() { } 
    public MyException(string message) : base(message) { } 
    public MyException(string message, Exception inner) : base(message, inner) { } 
    protected MyException(
     System.Runtime.Serialization.SerializationInfo info, 
     System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) { } 
} 
0

No se preocupe demasiado acerca de este tipo de situación; solo crea un tipo de resultado para encapsular toda esta lógica.

public class ValueResult 
{ 
    public Failure FailureDetails {get;set;} 
    public bool Success {get;set;} 
    public bool HasValue {get;set;} 
    public object Value {get;set;} 
} 

y

var result = HasValue(); 
if(result.Success) 
    DoSomething(result.Value); 
else if(!result.Success) 
    LogFailure(result.FailureDetails); 
+1

... y obtienes toda la elegancia y robustez de la programación con los códigos de error del estilo C ... ¿cómo informas a las personas que llamaron sobre el error? –

+0

Al menos hágalo genérico, en lugar de usar un objeto simple. – harms

+0

@harms Value es lo que él quiera que sea; la solución no pretende ser una clase genérica para usar en cualquier situación (no es necesario reemplazar el manejo de excepciones), solo otra opción para su pregunta. Entonces, si Value debe ser un MintyGreenChocolate, simplemente puede cambiarlo por objeto. – Will

1

Inerit de Excepción y hacer que su objeto serializable

0

Tienes que hacer una clase que hereda de Exception así:

[Serializable] 
public class Failure: Exception 
{ 
    public string ErrorMessage 
    { 
     get 
     { 
     return base.Message.ToString(); 
     } 
    } 

} 

y luego

catch(Exception ex) 
{ 
    throw new Failure(
      "exception message here", ex.messege); 
} 
0

Además siempre se puede utilizar Enterprise Library para el control de excepciones excepciones personalizadas proporcionar su propia clase para el manejo de excepciones, el formato tipo, el registro etc ...

try 
{ 
} 
catch(Exception ex) 
{ 
    bool rethrow = ExceptionPolicy.HandleException(ex, "My Custom Policy"); 
    if (rethrow) 
    { 
     throw; 
    } 
} 
finally 
{ 
} 

Ejemplos:

http://weblogs.asp.net/sukumarraju/archive/2009/10/04/microsoft-enterprise-library-4-1-exception-handling-block.aspx

http://www.imason.com/imason_Blogs/b/suleman_ibrahim/archive/2009/05/25/configuring-enterprise-library-4-0-for-exception-handling-and-logging.aspx

Cuestiones relacionadas