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。没有例外。谢谢你的把戏。