返回结果为T的对象

时间:2018-08-05 15:36:02

标签: c# asp.net-core

调用方法时,我需要返回对象值。但是,我还需要将错误消息与这些方法一起传递。因此,我想到了一个像这样的对象:

public class ReturnObject
{
    public bool Success { get; set; }
    public IEnumerable<string> Errors { get; set; }
    public dynamic Result { get; set; }
}

现在,从我的服务中,我可以调用此函数并返回任何我想要的错误。但是,问题是这不是类型安全的,我每次都需要转换结果。因此,我的目标是使其输入安全。这是我想到的方法:

public class ReturnObject<T>
{
    public bool Success { get; set; }
    public IEnumerable<string> Errors { get; set; }
    public T Result { get; set; }
}

现在,我经常返回该对象,因此,我创建了一个服务,该服务将向我返回该对象。尝试使我的代码保持干燥。服务看起来像这样:

public class ResultService<T>
{
    public ReturnObject<T> GetGoodResult(T result)
    {
        return new ReturnObject { Success = true, Result = result };
    }


    public ReturnObject<T> GetGoodResult(T result, IEnumerable<string> errors)
    {
        return new ReturnObject { Success = false, Errors = errors, Result = result };
    }
}

现在让我们说我有一项服务,我想从中使用它。

public class BookService
{
    private ResultService<book> _resultServiceBook = new ResultService<Book>();
    private ResultService<string> _resultServiceString = new ResultService<string>();

    public ReturnObject<Book> GetBook() 
    {
        return _resultServiceBook.GetGoodResult(new Book());
    }

    public ReturnObject<string> GetBookName(bookId)
    {
        return _resultServiceString.GetGoodResult(GetBookNameFromRepo(bookId));
    }
}

如您所见,对于我要返回的每种类型,我必须使用该类型创建一个新的ResultService实例。我似乎找不到更好的方法来实现这一目标。我不喜欢这样,我必须多次创建相同的服务以保持其类型安全。

以防万一,当我说“类型安全”时我的意思不是很清楚,我的意思是Visual Studio将在我仍在编码时捕获类型比较。

2 个答案:

答案 0 :(得分:4)

您不需要在类级别指定泛型类型,因为您没有任何状态依赖于在该级别指定的泛型。相反,只需在方法上指定通用参数即可。

此外,没有理由将其作为服务使用,而是在寻找Factory模式:

public static class ResultFactory
{
    public static ReturnObject<T> GetGoodResult<T>(T result)
    {
        return new ReturnObject { Success = true, Result = result };
    }


    public static ReturnObject<T> GetGoodResult<T>(T result, IEnumerable<string> errors)
    {
        return new ReturnObject { Success = false, Errors = errors, Result = result };
    }
}

然后您可以简单地使用它:

var data = new SomeClass();
var result = ResultFactory.GetGoodResult(data);

result将是ReturnObject<SomeClass>

答案 1 :(得分:0)

您可以做两件事。

  1. 添加通用类型约束new(),确保该类具有无参数构造函数,并且可以在new上调用T

  2. 使方法通用。

public class GenericService
{
    public ReturnObject<T> GetResult<T>() 
        where T : new()
    {
        return new ResultService<T>().GetGoodResult(new T());
    }
}

如果您不想每次都创建新服务,请将服务设为单例

public class ResultService<T>
{
    public static readonly ResultService<T> Instance = new ResultService<T>();

    ...
}

通用服务变为

public class GenericService
{
    public ReturnObject<T> GetResult<T>() 
        where T : new()
    {
        return ResultService<T>.Instance.GetGoodResult(new T());
    }
}