Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当使用NotSupportedException时是坏的?_C#_Design Patterns_Interface - Fatal编程技术网

C# 当使用NotSupportedException时是坏的?

C# 当使用NotSupportedException时是坏的?,c#,design-patterns,interface,C#,Design Patterns,Interface,我正在建立一个本地化目录,在设计上遇到了一个难题。现在,目录存储了一个字典来存储翻译,其中IString可以是两种类型:单数或复数。这是IString的简化版本: public interface IString { void SetSingular(string singular); string GetSingular(params object[] args); void SetPlural(PluralCategory category, string plu

我正在建立一个本地化目录,在设计上遇到了一个难题。现在,目录存储了一个
字典
来存储翻译,其中
IString
可以是两种类型:
单数
复数
。这是IString的简化版本:

public interface IString
{
    void SetSingular(string singular);

    string GetSingular(params object[] args);

    void SetPlural(PluralCategory category, string plural);

    string GetPlural(PluralCategory category, params object[] args);
}
public enum SingularOrPluralCategory {
    Singular,
    // The rest of the PluralCategory enum values
}
public class StringForm {
    public string Text {get; private set;}
    public SingularOrPluralCategory Category {get; private set;}
}
public interface IString {
    // You may want to omit the setter from the interface, adding it to the class instead
    void SetForm(SingularOrPluralCategory category, string plural);
    StringForm GetForm(SingularOrPluralCategory category, params object[] args);
}
然后,当我实现
Singular
时,我为复数方法抛出一个
NotSupportedException
,该异常被目录捕获,而
multilar
也为单数方法抛出一个异常

public class Singular : IString
{
    // ...

    public string GetPlural(PluralCategory category, params object[] args)
    {
        throw new NotSupportedException(string.Format(
            "Singular strings don't support GetPlural({0}, {1})",
            category, args));
    }

    public void SetPlural(PluralCategory category, string plural)
    {
        throw new NotSupportedException(string.Format(
            "Singular strings don't support SetPlural({0}, {1})",
            category, plural));
    }
}
这种设计源于这样一个要求,即键对于奇数和复数都必须是唯一的,但我觉得实现非相关方法和抛出
NotSupportedException
的味道不好

第二种设计是存储一个
字典
,用于键检查,其中
StringType
是一个枚举,然后根据
StringType
的值使用两个额外的字典
Dictionary
Dictionary
。这使它更复杂一点,但并没有打破接口的概念

那么,你认为呢?我的第一个想法是对
NotSupportedException
的错误使用吗?我应该选择第二种设计还是其他

编辑:基于@dasblinkenlight思想,一个更清晰的解决方案是将接口方法统一为一个
单数
复数
。奇点只有一个
复数类别。无
,而复数永远不允许包含此类别。这受到setter方法的限制,未包含由特定实现定义的接口(setter方法不显示在下面)

公共接口IString
{
字符串GetString(PluralCategory类别,参数对象[]args);
布尔哈斯分类(多分类);
}
公共类单数:IString
{
私有字符串文本;
公共字符串GetString(PluralCategory类别,参数对象[]args)
{
if(category==PluralCategory.None)
{
if(Text==null | | args==null | | args.Length==0)
{
返回文本;
}
返回string.Format(文本,参数);
}
返回null;
}
公共业务类别(多个类别)
{
返回类别==多个类别。无;
}
}
公共类复数:IString
{
专用词典文本=新词典();
公共字符串GetString(PluralCategory类别,参数对象[]args)
{
字符串文本;
if(文本.TryGetValue(类别,输出文本))
{
if(text==null | | args==null | | args.Length==0)
{
返回文本;
}
返回string.Format(文本,参数);
}
返回null;
}
公共业务类别(多个类别)
{
返回文本。ContainsKey(类别);
}
}

你是对的,在这种情况下抛出
NotSupportedException
不是一个好主意。通常,实现接口是为了提供一组公共操作,这些操作“统一”一组不同的类,为一组公共操作提供不同的实现

然而,在您的例子中,不同的类无法“统一”:它们不仅保留自己的实现,还保留自己的接口。当您尝试统一使用它们时,代码会引发异常。与将它们保留为
对象相比,公共界面并没有给您带来太多好处-用户必须在进行调用之前知道
IString
背后的类,否则他们可能会看到
NotSupportedException

有几种方法可以解决这个问题:一种方法是统一单数和复数方法,返回比简单的
字符串更复杂的答案:

public interface IString
{
    void SetSingular(string singular);

    string GetSingular(params object[] args);

    void SetPlural(PluralCategory category, string plural);

    string GetPlural(PluralCategory category, params object[] args);
}
public enum SingularOrPluralCategory {
    Singular,
    // The rest of the PluralCategory enum values
}
public class StringForm {
    public string Text {get; private set;}
    public SingularOrPluralCategory Category {get; private set;}
}
public interface IString {
    // You may want to omit the setter from the interface, adding it to the class instead
    void SetForm(SingularOrPluralCategory category, string plural);
    StringForm GetForm(SingularOrPluralCategory category, params object[] args);
}

现在,单数实现将返回
StringForm
,其中包含
Category
中的
singular
值,而复数实现将返回带有多个复数类别之一的
StringForm
。尝试在
IString
的单数子类上设置复数类别可能仍然是一个错误,但是您可以通过将setter移动到类上来修复这一问题,使其无法在
IString
的单数子类上调用具有类别的setter。嗯,没关系。残疾手术例外对我来说总是更有意义。不要给我打电话问我为什么不支持。Egad.别忘了,如果你用它进行本地化,现在就停下来。你已经有很多麻烦了。你考虑过性别吗?@Guillaume这是基于CLDR复数形式的,包括双重形式。@Stu是的,我考虑过性别,但我不支持性别差异,或者至少在第一次迭代中不支持。与大多数工具一样,一般的方法是制定与性别无关的字符串,或者在涉及性别时请求不同的字符串键。我现在使用的是一种变体,跳过
StringForm
,直接返回字符串
IString
有一个方法
stringgetstring(PluralCategory,params object[]args)
Singular
实现只需要一个
PluralCategory.None
,否则返回null。没有例外。谢谢你的把戏。