编辑: 基本上我希望能够使用以下机制作为我原始问题的答案:
void MethodA()
{
MethodB();
//This code will never be reached because 'return' from the inline MethodB is executed.
//... More code here
}
[Attribute(Inline)]
ReturnValue MethodB()
{
return;
}
当然上面的例子本身就没用了,当然会把更多的逻辑放在MethodB中,但为了简洁,我把它留了下来。
原始问题:
在已经开发1年的项目中,选择执行以下操作。每个函数都返回ReturnValue<T>
而不是抛出异常,IsSuccessFul
布尔标志位于其上。像这样使用
var methodResult = MyMethod();
if (!methodResult .IsSuccesful)
{
return new ReturnValue<Type>(methodResult .ThrownException);
}
var value= methodResult.Value;
这种调用方法用于项目中的每个公共函数。您可以使用通用try catch来表示这需要比var value = MyMethod();
更多的代码行。特别是如果在范围内调用了十几个公共函数。
请不要与所选择的设计争论,我不是在讨论这是否是一个好的选择。
我想知道的是:有没有办法可以做到这一点
var value= TryMethod(MyMethod);
编译器或某个插件或其他任何东西会将此预编译时间转换为前面显示的完整模式。我的观点是,如果!IsSuccessFul函数应该返回。我可以写一个预编译时命令,为我做这个,但我希望有一些VisualStudio本身的片段/模板/内联方式。
感谢。
答案 0 :(得分:3)
应该像(模式一样简单 - 当然这里没有用,因为它基本上是身份,只是它会重新创建另一个ReturnValue<T>
- 所以不建议):
public static ReturnValue<T> TryMethod<T>(Func<ReturnValue<T>> method)
{
var methodResult = method();
if (!methodResult .IsSuccesful)
return new ReturnValue<T>(methodResult.ThrownException);
// I can only guess at this:
return methodResult;
}
但根据您的使用我认为您真的想要:
public static T TryMethod<T>(Func<ReturnValue<T>> method)
{
var methodResult = method();
if (!methodResult .IsSuccesful)
throw methodResult.ThrownException;
return methodResult.Value;
}
当然你可能需要进行多次重载(当你的方法需要参数时 - 比如:
public static T TryMethod<T,P>(Func<P,ReturnValue<T>> method, P p)
{
var methodResult = method(p);
// ...
您可能希望将它们放入静态扩展类中并执行:
public static T TryMethod<T>(this Func<ReturnValue<T>> method)
所以你可以写
var value = MyMethod.TryMethod();
等等。
总体而言,您的设计可能并不坏,但您应该考虑在SelectMany
类型中添加通常的functor-map和mondadic-bind操作(甚至可以在ReturnValue<T>
时使用LINQ):
public static ReturnValue<B> Map<A,B>(this ReturnValue<a> v, Func<A,B> f)
{
if (v.IsSuccesful) return new ReturnValue<B>(f(v.Value));
return new ReturnValue<B>(v.ThrownException);
}
public static ReturnValue<B> Bind<A,B>(this ReturnValue<a> v, Func<A,ReturnValue<B>> f)
{
if (v.IsSuccesful) return f(v.Value);
return new ReturnValue<B>(v.ThrownException);
}
Bind
使用此Bind
,您可以在此处执行此操作,我认为这就是您对范围的意思:
method().Bind(
value => {
// ... whatever you want to do with value - just return a ReturnValue<> at the end
});