将参数更改为返回值

时间:2015-04-10 08:11:47

标签: c#

我需要改变" out"到"返回"因为它使用起来会更舒服,但我真的不知道如何将这些功能转换为使用" return"不是" out"。 我有公共课,在这堂课我有bool方法

    public static bool GetParameter(this Dictionary<string, string> context, string parameterName, out int parameter) 
    { 
        string stringParameter; 
        context.TryGetValue(parameterName, out stringParameter); 
        return int.TryParse(stringParameter, out parameter); 
    }

我使用这个函数:

    private int _personID;
    public void SomeFunction()
    {
        _classInstance.Context.GetParameter("PersonID", out _personID);
    }

谢谢!

6 个答案:

答案 0 :(得分:3)

如果您不愿意使用out参数,我可以考虑两个不错的选择。不过,我应该说,从你的问题来看,看起来这是最好的方法。

我通常认为只有两个原因可以避免像这样的试用模型:

  • 涉及异步调用时。例如,测试数据库中是否存在某些内容,如果存在则返回它,则对out参数的效果不佳。
  • 当你正在做一些流利的事情时,例如在LINQ。

除此之外,它是一个可爱的模型,可以在不牺牲数据完整性的情况下传达大量信息(或对您可能期望的内容做出任何假设)。

此处的问题以及您当前返回bool的原因是处理错误。所以,你需要找到一种处理它们的替代方法。

这里的选择实际上取决于您期望的输入类型。

使用例外:

最简单的可能只是处理它们。让他们传播起来。如果找不到或无法解析某些内容,只需抛出异常。

使用异常来指导常规应用程序流程通常被认为是不好的做法,但可以解释“常规应用程序流程”是什么。所以一定要看看你的数据和情况。

public static int GetParameter(this Dictionary<string, string> context, string parameterName) 
{ 
    string stringParameter = context[parameterName];
    return int.Parse(stringParameter); 
}

使用null:

如果您希望异常或多或少地具有普通性,则可以返回null,并将合同设置为在发生非法事件时使用null。但是要小心在呼叫方面处理它!

类似于此的方法用于许多IndexOf函数,如string上的函数。它们返回-1而不是null,但原理是相同的 - 有一个你知道在实际数据中永远不会出现的值,并设置你的合同,这意味着“这不起作用。”

当我之前提到数据完整性和假设时,这就是我想到的。如果你想返回是的话,该字典确实包含一个空字符串,那应该是一个null int。突然间,你再也无法传达这一点了。是的,它有效,但这是你必须记住的决定。确保你的“失败”案例永远不会成功通过。

public static int? GetParameter(this Dictionary<string, string> context, string parameterName)
{ 
    string stringParameter; 
    if (!context.TryGetValue(parameterName, out stringParameter))
        return null;

    int ret;
    if (!int.TryParse(stringParameter, out ret))
        return null;

    return ret;
}

返回具体类型:

这需要一些开销,但它具有out参数的所有优点,而实际上并不需要它。

那就是说,我不确定我是否真的喜欢这么多。它给你的东西很棒,但是对于你使用它的东西,我感觉非常沉重。但无论如何, 是另一种选择。

public class ParseResult
{
    public ParseResult(bool IsSuccess, int Result)
    {
        this.IsSuccess = IsSuccess;
        this.Result = Result;
    }

    public bool IsSuccess { get; set; }
    public int Result { get; set; }
}

public static ParseResult GetParameter(this Dictionary<string, string> context, string parameterName)
{ 
    int ret;
    string stringParameter; 
    if (context.TryGetValue(parameterName, out stringParameter)
        && int.TryParse(stringParameter, out ret))
    {
        return new ParseResult(true, ret);
    }
    else
    {
        return new ParseResult(false, 0);
    }
}

答案 1 :(得分:0)

您似乎没有使用该方法的bool结果,因此您可以简单地编辑您的方法:

  public static int GetParameter(this Dictionary<string, string> context, string parameterName) 
    { 
        int parameter;
        string stringParameter; 
        context.TryGetValue(parameterName, out stringParameter); 
        int.TryParse(stringParameter, out parameter); 
        return parameter;
    }

答案 2 :(得分:0)

如果您知道参数始终存在,您可以通过这种方式进行转换:

public static string GetParameter(this Dictionary<string, string> context, 
                                     string parameterName) 
{ 
    string stringParameter = context[parameterName];
    return int.Parse(stringParameter);
}

答案 3 :(得分:0)

您可以执行以下操作:

public static int? GetParameter(this Dictionary<string, string> context, string parameterName) 
{ 
    string stringParameter; 
    if (!context.TryGetValue(parameterName, out stringParameter))
        return null;

    int value;
    if (!Int32.TryParse(stringParameter, out value))
        return null;

    return value;  
}

这使得该方法返回可为空的intnull。

使用它像:

int

答案 4 :(得分:0)

喜欢这个吗?

public static int GetParameter(this Dictionary<string, string> context, string parameterName) 
{ 
   string stringParameter; 
   context.TryGetValue(parameterName, out stringParameter); 
   int parameter;
   int.TryParse(stringParameter, out parameter); 
   return parameter;
}

private int _personID;
public void SomeFunction()
{
   _personID = _classInstance.Context.GetParameter("PersonID");
}

答案 5 :(得分:0)

首先,我想说绝大多数时候,你应该通过抛出异常来处理失败情况。

但是,偶尔您希望能够调用方法来获取该操作可能失败的值,但是您不想抛出异常来表示该失败。

这显然是一般概念,标准的.Net库使用TryXXX()模式解决了这个问题。

我个人不喜欢这样,因为它会使代码更难阅读,并且会干扰代理,异步和流畅的界面。

因此我们编写了自己的包装类来处理这些情况。这是一个简单的例子(真正的代码有很多代码契约,并且还允许可选的描述性错误字符串和异常):

public class Result<T>
{
    public static Result<T> Success(T value)
    {
        return new Result<T>(value, true);
    }

    public static Result<T> Failure()
    {
        return new Result<T>(default(T), false);
    }

    private Result(T value, bool succeeded)
    {
        _value        = value;
        _succeeded = succeeded;
    }

    public T Value
    {
        get
        {
            // Don't call this on failure!
            Trace.Assert(_succeeded);
            return _value;
        }
    }

    public bool Succeeded
    {
        get
        {
            return _succeeded;
        }
    }

    private readonly T    _value;
    private readonly bool _succeeded;
}

对于你的情况,你会使用这样的东西:

public static Result<int> GetParameter(this Dictionary<string, string> context, string parameterName)
{
    string stringParameter;
    context.TryGetValue(parameterName, out stringParameter);
    int result;

    if (int.TryParse(stringParameter, out result))
        return Result<int>.Success(result);
    else
        return Result<int>.Failure();
}

调用代码看起来像:

var personIdRetrieval = _classInstance.Context.GetParameter("PersonID");

if (personIdRetrieval.Succeeded)
    _personID = personIdRetrieval.Value;
else
    // Handle failure.