【问题标题】:Question about honest and dishonest function关于诚实和不诚实函数的问题
【发布时间】:2021-04-11 15:57:19
【问题描述】:

我目前正在阅读 Enrico Buonanno 的 C# 函数式编程。第 3 章包含一个练习(我会将练习缩短到相关部分):

// 5.  Write an implementations for the method in the `AppConfig` class below.
// Assume settings are of type string, numeric or date.

public class AppConfig
{
    NameValueCollection source;

    //public AppConfig() : this(ConfigurationManager.AppSettings) { }

    public AppConfig(NameValueCollection source) => this.source = source;

    public Option<T> Get<T>(string name)
    {
        throw new NotImplementedException("Your implementation here...");
    }
}

我想出的解决方案是

public Option<T> Get<T>(string name)
    {
        try { 
            return (T)Convert.ChangeType(source.Get(name), typeof(T)));
        } 
        catch { 
            return None; 
        };
    }

作者的解决方法是

public Option<T> Get<T>(string key)
        => source[key] == null
           ? None
           : Some((T)Convert.ChangeType(source[key], typeof(T)));

但这不是不诚实的功能吗?我可以有一个配置文件,其中包含一个值为“非数字”的键“SomeNumber”,所以如果我使用像Get&lt;int&gt;("SomeNumber") 这样的方法,这将抛出,而我的实现将返回 None。或者,我可能还有一个键为“SomeString”且值为“Goodbye World”的条目,我错误地尝试通过调用Get&lt;int&gt;("SomeString") 来检索它。

您可能会争辩说,抛出实际上是想要的结果,因为这是一个开发人员错误,应该突出显示。

想法?

【问题讨论】:

  • 您可能会争辩说,抛出实际上是想要的结果,因为这是一个开发人员错误,应该突出显示。 – 是的。您可以用值而不是异常来表示它,但可能与缺失键的值不同。

标签: c# functional-programming


【解决方案1】:

投掷其实是想要的结果是的。 .NET 中使用的模式是将不抛出的方法称为TrySomething(例如TryParseTryGetValue...)

我会在你的情况下补充一点,书中建议的方法有三个可能的“返回值”(我将在这里使用双引号):

  • 找到正确类型的密钥

  • 找不到密钥

  • 找到键但类型错误(抛出异常)

而你的只有两个:

  • 找到正确类型的密钥

  • 找不到密钥或找到但类型错误的密钥

因此,您的方法不清楚是否只是缺少该值(这可能是一个可选值)或配置中是否存在错误。

【讨论】:

    猜你喜欢
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    相关资源
    最近更新 更多