C#可以有一个通用的返回类型吗?

JL.*_*JL. 5 c#

这是一个返回true/false的典型函数;

private static bool hasValue()
{
    return true; 
}
Run Code Online (Sandbox Code Playgroud)

现在出错了,我想返回我自己的自定义错误对象的定义:

public class Failure
    {
        public string FailureDateTime { get; set; }
        public string FailureReason { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我原以为能够抛出这个自定义对象...

private static bool hasValue()
{
    try
        {
           ...do something
        }
    catch 
        {
         throw new Failure();
         }
    return true; 
}
Run Code Online (Sandbox Code Playgroud)

这是不可能的,我不想从System.IO.Exception派生Failure,因为我个人在C#中序列化异常时遇到了问题(这与.net v2有关).

这个问题的最佳实践/或理想解决方案是什么.我应该使用私有静态对象吗?或者是否有更简洁的方法来返回自定义对象或绕过错误的典型返回类型(不使用System.IO.Exception)?

我对使用对象也不是很疯狂,因为那时我需要使用强制转换和更多布尔值来验证结果.

Eli*_*sha 10

这种解决方案可能适合这种情况:

var exception = new Exception();
exception.Data.Add("Failure", new Failure());
throw exception;
Run Code Online (Sandbox Code Playgroud)

您可以抛出异常(建议定义您自己的异常类型),并使用Data字典来保存Failure.在catch代码中,您可以获取数据并将其序列化.如果您确实创建了自己的异常类型,则可以将失败放在属性上.

评论:我没有检查,但你确定异常不可序列化吗?

  • 我不认为它会正确序列化/反序列化.至少,除非故障本身是可序列化的. (3认同)

Mar*_*ers 7

我不想从System.IO.Exception派生Failure,因为无法在C#中序列化异常.

这个问题所基于的假设是你不能序列化从中派生的异常IOException.但是,我希望挑战这一假设.IOException被标记为Serializable.您所要做的就是将您的子类标记为可序列化.

请参阅IOException的文档:

[SerializableAttribute]
[ComVisibleAttribute(true)]
public class IOException : SystemException
Run Code Online (Sandbox Code Playgroud)


Igo*_*aka 6

如果要创建自己的异常类,则需要从System.Exception(或其任何其他非子sealed类)派生.无法序列化您正在谈论的可能是您没有实现序列化构造函数.

Visual Studio有一个代码片段,用于创建用于子类化异常的推荐模板.您可以通过键入exception并按tab两次来获取它.

这是出来的:

[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) { }
}
Run Code Online (Sandbox Code Playgroud)