1

您将如何重构这两个类以抽象出相似之处?一个抽象类?简单的继承?重构的类会是什么样子?

public class LanguageCode
{
    /// <summary>
    /// Get the lowercase two-character ISO 639-1 language code.
    /// </summary>
    public readonly string Value;

    public LanguageCode(string language)
    {
        this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
    }

    public static LanguageCode TryParse(string language)
    {
        if (language == null)
        {
            return null;
        }

        if (language.Length > 2)
        {
            language = language.Substring(0, 2);
        }

        try
        {
            return new LanguageCode(language);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}

public class RegionCode
{
    /// <summary>
    /// Get the uppercase two-character ISO 3166 region/country code.
    /// </summary>
    public readonly string Value;

    public RegionCode(string region)
    {
        this.Value = new RegionInfo(region).TwoLetterISORegionName;
    }

    public static RegionCode TryParse(string region)
    {
        if (region == null)
        {
            return null;
        }

        if (region.Length > 2)
        {
            region = region.Substring(0, 2);
        }

        try
        {
            return new RegionCode(region);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}
4

7 回答 7

2

这取决于,如果他们不打算做更多,那么我可能会让他们保持原样 - 恕我直言,在这种情况下,分解出的东西可能会更复杂。

于 2008-09-16T09:16:06.363 回答
0

这是一个相当简单的问题,对我来说,它闻起来非常像家庭作业。

您显然可以看到代码中的常见位,我很确定您可以通过将这些东西放入超类中自己尝试一下。

于 2008-09-16T09:19:08.600 回答
0

您可以将它们组合成一个Locale类,该类存储语言代码和区域代码,具有区域和语言的访问器以及一个解析函数,该函数还允许像“en_gb”这样的字符串......

这就是我看到在各种框架中处理语言环境的方式。

于 2008-09-16T09:21:05.820 回答
0

就目前而言,这两个不会因为静态方法而很好地重构。

您要么最终在基类上使用某种工厂方法,该方法返回该基类的类型(随后需要强制转换),要么您需要某种额外的辅助类。

考虑到额外代码的数量以及随后转换为适当类型的数量,这是不值得的。

于 2008-09-16T09:21:27.253 回答
0

我确信有更好的基于泛型的解决方案。但还是试了一下。

编辑:正如评论所说,静态方法不能被覆盖,因此一种选择是保留它并使用 TwoLetterCode 对象并强制转换它们,但是,正如其他人已经指出的那样,这是相当没用的。

这个怎么样?

public class TwoLetterCode {
    public readonly string Value;
    public static TwoLetterCode TryParseSt(string tlc) {
        if (tlc == null)
        {
            return null;
        }

        if (tlc.Length > 2)
        {
            tlc = tlc.Substring(0, 2);
        }

        try
        {
            return new TwoLetterCode(tlc);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}
//Likewise for Region
public class LanguageCode : TwoLetterCode {
    public LanguageCode(string language)
    {
        this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
    }
    public static LanguageCode TryParse(string language) {
        return (LanguageCode)TwoLetterCode.TryParseSt(language);
    }
}
于 2008-09-16T09:21:48.610 回答
0
  1. 创建一个通用基类(例如AbstractCode<T>
  2. 添加抽象方法,例如

    protected T GetConstructor(string code);
    
  3. 在基类中覆盖,例如

    protected override RegionCode GetConstructor(string code)
    {
        return new RegionCode(code);
    }
    
  4. 最后,对 做同样的事情string GetIsoName(string code),例如

    protected override GetIsoName(string code)
    {
        return new RegionCode(code).TowLetterISORegionName;
    }
    

这将重构两者。克里斯金普顿确实提出了一个重要的问题,即努力是否值得。

于 2008-09-16T09:23:42.193 回答
0

除非您有强烈的重构理由(因为您将在不久的将来添加更多类似的类),否则为这样一个小而人为的示例更改设计的代价将克服这种情况下维护或开销的收益。无论如何,这是一个基于泛型和 lambda 表达式的可能设计。

public class TwoLetterCode<T>
{
    private readonly string value;

    public TwoLetterCode(string value, Func<string, string> predicate)
    {
        this.value = predicate(value);
    }

    public static T TryParse(string value, Func<string, T> predicate)
    {
        if (value == null)
        {
            return default(T);
        }

        if (value.Length > 2)
        {
            value = value.Substring(0, 2);
        }

        try
        {
            return predicate(value);
        }
        catch (ArgumentException)
        {
            return default(T);
        }
    }

    public string Value { get { return this.value; } }
}

public class LanguageCode : TwoLetterCode<LanguageCode>  {
    public LanguageCode(string language)
        : base(language, v => new CultureInfo(v).TwoLetterISOLanguageName)
    {
    }

    public static LanguageCode TryParse(string language)
    {
        return TwoLetterCode<LanguageCode>.TryParse(language, v => new LanguageCode(v));
    }
}

public class RegionCode : TwoLetterCode<RegionCode>
{
    public RegionCode(string language)
        : base(language, v => new CultureInfo(v).TwoLetterISORegionName)
    {
    }

    public static RegionCode TryParse(string language)
    {
        return TwoLetterCode<RegionCode>.TryParse(language, v => new RegionCode(v));
    }
}
于 2008-09-16T09:41:03.277 回答