C# 扩展方法返回<;T>;而不是结果<;T>;
我正在学习Vladimir Khorikov的C# 扩展方法返回<;T>;而不是结果<;T>;,c#,generics,extension-methods,func,C#,Generics,Extension Methods,Func,我正在学习Vladimir Khorikov的Result类,以及如何使用它来链接结果操作 他们的原创文章可以找到 可以找到他们的原始结果类代码 我编辑的结果类代码如下: public class Result { private bool _isSuccess; private string _errorMsg = ""; public bool IsSuccess() { return _isSuccess; } publi
Result
类,以及如何使用它来链接结果操作
他们的原创文章可以找到
可以找到他们的原始结果
类代码
我编辑的结果
类代码如下:
public class Result
{
private bool _isSuccess;
private string _errorMsg = "";
public bool IsSuccess()
{
return _isSuccess;
}
public bool IsFailure()
{
return !_isSuccess;
}
public string ErrorMsg()
{
return _errorMsg;
}
public Result(bool isSuccess, string errorMsg)
{
bool errorMsgIsEmpty = string.IsNullOrEmpty(errorMsg);
if (isSuccess && !errorMsgIsEmpty)
{
throw new Exception("cannot have error message for successful result");
}
else if (!isSuccess && errorMsgIsEmpty)
{
throw new Exception("must have error message for unsuccessful result");
}
_isSuccess = isSuccess;
if (!errorMsgIsEmpty)
{
_errorMsg = errorMsg;
}
}
public static Result Fail(string errorMsg)
{
return new Result(false, errorMsg);
}
public static Result<T> Fail<T>(string errorMsg)
{
return new Result<T>(default(T), false, errorMsg);
}
public static Result OK()
{
return new Result(true, "");
}
public static Result<T> OK<T>(T value)
{
return new Result<T>(value, true, "");
}
public static Result Combine(params Result[] results)
{
foreach (Result result in results)
{
if (result.IsFailure())
{
return result;
}
}
return OK();
}
}
public class Result<T> : Result
{
private T _value;
public T Value()
{
return _value;
}
public Result(T value, bool isSuccess, string errorMsg) : base(isSuccess, errorMsg)
{
_value = value;
}
}
下面是在水果上操作的类:
public class FruitOperator
{
public static Result<Fruit> AddAttribToFruit(Fruit fruit, string attrib, bool fail)
{
if (fail)
{
return Result.Fail<Fruit>("failed");
}
fruit.AddAttrib(attrib);
return Result.OK<Fruit>(fruit);
}
public static void MarkFruitAsBad(Fruit fruit)
{
fruit.isBad = true;
}
}
我的问题是在下一个操作中尝试使用OnSuccess
的结果时:
Fruit fruit = new Fruit("apple");
Result<Fruit> fruitResult = FruitOperator.AddAttribToFruit(fruit, "big", false)
.OnSuccess(FruitOperator.AddAttribToFruit, fruit, "red", true)
.OnFailure(lastFruitResult => FruitOperator.MarkFruitAsBad(lastFruitResult.Value()));
水果=新水果(“苹果”);
Result-fruitResult=FruitOperator.AddAttribToFruit(水果,“大”,假)
.OnSuccess(水果操作员.AddAttribToFruit,水果,“红色”,真)
.OnFailure(lastFroothResult=>FroothOperator.MarkFroothAsBad(lastFroothResult.Value());
上面,lastFruitResult
实际上是一个水果
,而不是我预期的结果
我的扩展方法签名是否有问题,或者我是否需要在使用它们时进行更改?您在OnFailure
中的签名有点错误。将其更改为OnFailure(此结果为结果,动作为动作)
基本上,操作
是接受多个参数的委托。与Func
的区别在于Action
不返回值
OnFailure(此结果为动作动作)
将允许消费者通过输入类型为T
的动作。在您的例子中,T
是水果
,因为它实际上是在AddAttribToFruit
中定义的,因为它返回结果
将签名更改为:
OnFailure(此结果为结果,动作为动作)
它将允许消费者创建一个类型为Result
的动作,在您的情况下为Result
您的OnFailure
应该看起来像这样:
public static Result<T> OnFailure<T>(this Result<T> result, Action<Result<T>> action)
{
if (result.IsFailure())
{
action(result); // Note that result is Result<T> and action takes Result<T> as parameter
}
return result;
}
失败时的公共静态结果(此结果,操作)
{
if(result.IsFailure())
{
action(result);//注意result是result,action以result作为参数
}
返回结果;
}
lastFruitResult
将是操作中定义的类型。仔细查看OnFailure中的Action
(此结果,操作操作)
从第一眼开始。。。更改操作操作
->操作操作
在OnFailure
@smoksnes嘿,它确实起作用了!你能加上这个作为回答吗?这样我就可以接受了?另外,您是否可以添加一个解释,说明更改失败时的签名如何影响我从成功时的签名?@Floating您不会从成功时的签名中获得最后的结果?这是从哪里来的?我只是想在这里补充最后的结论Func
和Action
确定使用someIdentifer=>
时从被扩展对象获取的值(和数据类型)。
Fruit fruit = new Fruit("apple");
Result<Fruit> fruitResult = FruitOperator.AddAttribToFruit(fruit, "big", false)
.OnSuccess(FruitOperator.AddAttribToFruit, fruit, "red", true)
.OnFailure(lastFruitResult => FruitOperator.MarkFruitAsBad(lastFruitResult.Value()));
public static Result<T> OnFailure<T>(this Result<T> result, Action<Result<T>> action)
{
if (result.IsFailure())
{
action(result); // Note that result is Result<T> and action takes Result<T> as parameter
}
return result;
}