我在我的项目中使用通用属性,但我不知道,使用它们是否有任何缺点,请告诉我一个场景,它们有一个缺点?我的部分代码如下。
public class GenericResult<T>
{
public T Data { get; set; }
public bool IsSuccess { get; set; }
public string Message { get; set; }
}
public GenericResult<int> AddCategory(TCategory tCategory)
{
GenericResult<int> result = new GenericResult<int>();
//business logic validation,dont make sense,only example :)
if (tCategory.Name.Lenght > 100)
{
result.IsSuccess = false;
result.Message = "Category Name length is too long";
result.Data = 0;
}
//handle .net runtime error//may be database is not aviable.
try
{
result.Data = this.catalogRepository.AddCategory(tCategory);
result.IsSuccess = true;
}
catch (Exception ex)
{
result.Data = 0;
result.IsSuccess = false;
result.Message = ex.Message;
}
return result;
}
public GenericResult<IEnumerable<TCategory>> GetCategoryHierarchy(TCategory parentCategory)
{
GenericResult<IEnumerable<TCategory>> result = new GenericResult<IEnumerable<TCategory>>();
try
{
IEnumerable<TCategory> allCategories = catalogRepository.GetAllCategories();
result.Data = GetCategoryHierarchy(allCategories, parentCategory);
result.IsSuccess = true;
}
catch (Exception ex)
{
result.IsSuccess = false;
result.Data = null;
result.Message = ex.Message;
}
return result;
}
答案 0 :(得分:4)
我宁愿删除IsSuccess
和Message
并仅返回该对象。见下文......
看看我的问题Good practices when handling Exceptions in C#。您将返回错误,而不是抛出异常,而在.NET中,则不建议这样做。
不要返回错误代码。例外是在框架中报告错误的主要方法。
我在阅读的一些文章/书籍中建议您正在做什么,包括The Pragmatic Programmer: From Journeyman to Master和this Joel Spolsky article,但正如MSDN所述, .NET 例外情况是为此目的更好。
修改强>
如果您仍然希望这样做(即使可能给使用您的代码的开发人员带来一些问题),我认为,一般来说,这可能是一个好方法。实际上,我将编辑我在此答案上链接的问题,以便为您的代码添加一个链接,以替代返回错误,而不是在.NET中抛出异常
答案 1 :(得分:4)
如果您不想抛出异常但更喜欢返回包含错误或值的结果,即在某些情况下可以使用MayBe
。但说实话,在这种情况下,我宁愿抛弃/通过异常。
我更喜欢将不可变结构作为MayBe
而不是像你那样返回可变类。它与Nullable<T>
非常相似,除了它适用于引用类型并且可以存储错误。类似的东西:
public struct MayBe<T>
{
private T value;
private Exception error;
public bool HasValue{get{return error==null;}}
public T Value
{
if(error!=null)
throw error;
else
return value;
}
public static MayBe<T> CreateError(Exception exception)
{
return new MayBe<T>(default(T),exception);
}
public static MayBe<T> CreateValue(T value)
{
return new MayBe<T>(value,null);
}
public static implicit operator MayBe<T>(T value)
{
return CreateValue(value);
}
public override string ToString()
{
if(HasValue)
return "Value: "+Value.ToString();
else
return "Error: "+Error.GetType().Name+" "+Error.Message;
}
}
您的代码变为
public MayBe<int> AddCategory(TCategory tCategory)
{
try
{
return this.catalogRepository.AddCategory(tCategory);
}
catch (Exception ex)
{
return MayBe<int>.CreateError(ex);
}
return result;
}
public MayBe<IEnumerable<TCategory>> GetCategoryHierarchy(TCategory parentCategory)
{
try
{
IEnumerable<TCategory> allCategories = catalogRepository.GetAllCategories();
return allCategories;
}
catch (Exception ex)
{
return MayBe<int>.CreateError(ex);
}
return result;
}
我看到这个实现的一个问题是异常不是完全不可变的。如果相同的MayBe<T>
抛出多个线程,则可能会导致问题。也许有人可以建议更好的实施。
答案 2 :(得分:2)
如果您的应用程序范围完全在.NET范围内,那么这种模式没有用,正如其他人提到的那样,您应该抛出异常并且您可能想要更改异常。
但是,如果您的应用程序范围很广,可能包括任何其他客户端框架,可能通过JSON,Web服务等,并且如果客户端框架不能正确支持异常,则此模式可能很有用。例如,在基于JSON的Javascript调用中,您将始终期望结果,以及指示服务器端是否出现故障的消息。客户端失败可能是服务器端故障或网络故障,通常所有客户端框架都会检测到并且只报告网络故障和不正确编码的框架将导致混乱,当您在客户端无法获得任何错误报告时服务器端。
这个模式非常有用的另一个地方是,当你在UI中或在其他人的框架内编写一些插件时,只有抛出异常会导致不希望的结果,因为有异常后,第三方框架可能会说“意外错误”因为他们没有,他们不会理解你的例外。这种模式在其他人的框架内部非常有用,并且无论您的失败如何,仍然可以让底层框架正常工作。您可能可以在应用程序框架内正确地进行通信。
我最近看到过,它仍然是一个错误,如果您设置的图像来源是一个Web地址且不存在,WPF会停止处理一些待处理的UI相关活动。您将看到跟踪网络相关的异常,但WPF将不完全停止处理待处理任务中的任何内容,并且应用程序仍可正常工作,但它确实会影响其中不应该的其他UI元素。
答案 3 :(得分:0)
使用自动属性非常好,我没有看到任何问题。
但是我强烈劝说这个模式使用一个类来告诉外面的世界失败了。当某些事情严重失败时,返回null或抛出异常。
HTH
马里奥