C# Possible to have a generic return type?
Here is a typical function that returns either true/false;
private static bool hasValue()
{
return true;
}
Now on an error, I would like to return my own custom error object with definition:
public class Failure
{
public string FailureDateTime { get; set; }
public string FailureReason { get; set; }
}
I would have expected to be able to throw this custom object for example...
private static bool hasValue()
{
try
{
// do something
}
catch
{
throw new Failure();
}
return true;
}
This is not possible, and I don't want to derive Failure from System.IO.Exception because I have personally had issues serializing exceptions in C# (This was with .net v2).
What is the best practice / or ideal solution to this problem开发者_开发百科. Should I just work with private static object? Or is there a cleaner way to return a custom object or bypass the typical return type on an error (not using System.IO.Exception
)?
I am not entirely wild about using an object either, because then I need to validate the result by using casting and more boolean.
This kind of solution may fit to this case:
var exception = new Exception();
exception.Data.Add("Failure", new Failure());
throw exception;
You can throw the exception (recommended to define your own exception type), and use the Data dictionary to hold the Failure. In the catch
code you can take the data and serialize it. If you do create your own exception type you can place the Failure on a property.
Comment: I didn't check it, but are you sure exceptions are not serializable?
I don't want to derive Failure from System.IO.Exception because of the inability to serialize an exception in C#.
The assumption that this question is based on is that you cannot serialize exceptions derived from IOException
. However I wish to challenge this assumption. IOException
is marked as Serializable
. All you have to do is mark your subclass as serializable too.
See the documentation for IOException:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class IOException : SystemException
You need to derive from System.Exception
(or any other non-sealed
subclass of it) if you want to create your own exception class. Failure to serialize that you are talking about is likely the fact that you didn't implement the serialization constructor.
Visual Studio has a code snippet that creates a recommended template for subclassing exception. You can get it by typing exception
and pressing tab twice.
This is what comes out:
[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) { }
}
Inerit from Exception and make your object serializable
Don't worry too much about this kind of situation; just create a result type to encapsulate all this logic.
public class ValueResult
{
public Failure FailureDetails {get;set;}
public bool Success {get;set;}
public bool HasValue {get;set;}
public object Value {get;set;}
}
and
var result = HasValue();
if(result.Success)
DoSomething(result.Value);
else if(!result.Success)
LogFailure(result.FailureDetails);
Also you can always use Enterprise Library Exception Handling for custom exceptions providing your own class for exception handling, formatting type, logging etc...
try
{
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, "My Custom Policy");
if (rethrow)
{
throw;
}
}
finally
{
}
Examples:
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
You have to make a class that inherits from Exception like this :
[Serializable]
public class Failure: Exception
{
public string ErrorMessage
{
get
{
return base.Message.ToString();
}
}
}
and then
catch(Exception ex)
{
throw new Failure(
"exception message here", ex.messege);
}
精彩评论