2013-09-03 2 views
2

Я ищу реалистичный многоязычный класс плюрализации, и я основываю его на интерфейсе IPlural, который я создал.Создание экземпляра динамического объекта C# на основе языка или CultureInfo

IPlural определяет функцию pluralType

string pluralType(float value); 

Для каждого языка, который я хочу, чтобы поддержать я планирую создать файл класса, который реализует набор правил, который определяет pluralType, который может быть «ноль», «один» «два», «несколько», «много» или «другое». Функция проста, вы передаете числовое значение, вы получаете строку.

Моя проблема заключается в том, что я хочу выбрать одну из реализаций IPlural на основе существующих в настоящее время CultureInfo/Language пользователей, не имея массового оператора switch, как я могу это сделать?

Все мои классы называются такие вещи, как:

  • Plural_en
  • Plural_pl
  • Plural_bs

где последние два символа языка (в данном случае, как правило, независимым от локали).

Эти классы все реализовать IPlural, и я предполагаю, что он должен работать следующим образом ...

IPlural pluraliser = new "dynamically chosen pluraliser class" 
string pt = pluraliser.pluralType(5); 

Дело в том, я не знаю, если это вообще возможно?

Любые указатели были бы наиболее желанными.

Благодаря

+0

Я считаю, что существуют некоторые языки, например, 2 имеет различные формы в зависимости от, например, полов или других модифицирующих форм. Как вы планируете это решать? –

+1

Я думаю, что этот дизайн плюрализации очень упрощен и не будет работать в общем случае; обычно вам нужно локализовать всю строку в несколько модифицированных форм; Кроме того, число и характер этих форм могут быть ... «довольно сложными». –

+0

На македонии одна книга - «edna kniga», одно платье - «eden fustan», две книги - «dve knigi», две платья - «dva fustani», а три книги/платья - «три книги/фустани». – SWeko

ответ

1

Есть два относительно простых решений:

  • Используйте Dictionary<string,Func<IPlural>> построить Plural_.. классов или
  • Используйте отражение, чтобы найти класс с именем в соответствии с вашей конвенцией.

Вот как можно реализовать первое решение:

private readonly IDictionary<string,Func<IPlural>> LangToPlural = 
    new Dictionary<string,Func<IPlural>> { 
     {"en",() => new Plural_en()} 
    , {"pl",() => new Plural_pl()} 
    , {"bs",() => new Plural_bs()} 
    , ... 
    }; 
public IPlural MakePluralForLanguageCode(string langCode) { 
    Func<IPlural> res; 
    if (LangToPlural.TryGetValue(langCode, out res)) { 
     return res(); 
    } 
    return new Plural_en(); // Provide a default 
} 

Вот как можно реализовать второе решение:

var typeName = typeof(IPlural).Assembly.FullName.+".Plural_"+langCode; 
var plType = Type.GetType(typeName); 
if (plType == null) retunr new Plural_en(); // Provide a default 
var constr = plType.GetConstructor(new Type[0]); 
return (IPlural)constr.Invoke(new Type[0]); 

Преимущество первого способа является его простота; преимущество второго метода заключается в его способности собирать дополнительные реализации Plural_xy по мере их появления, без каких-либо дополнительных модификаций кода.

+0

Не думал об использовании отражения. У нас уже есть фабрика объектов для основной архитектуры системы, но она не совсем подходит для вопроса о требованиях к языку, но отражение действительно делает работу очень красивой. Благодарю. – PaulV

3

Что вам нужно, это называется Factory Pattern

Вы можете иметь класс с именем PluralizerFactory, что бы сделать:

public static IPlural CreatePluralizer(string language) 
{ 
    if (language=="en") 
    return new Plural_en(); 
    if (language=="pl") 
    return new Plural_pl(); 
    if (language=="bs") 
    return new Plural_bs(); 
    throw new ArgumentException("invalid language"); 
} 

Это может не быть использован

IPlural pluraliser = PluralizerFactory.CreatePluralizer("en"); 
string pt = pluraliser.pluralType(5); 

Код в методе CreatePluralizer c быть таким же уродливым или умным, как вам нравится. Важно то, что ваш код вызова защищен от него, поэтому вызывающий код даже не знает, что существуют разные классы для «en» и «pl».

Эта реализация является одной из самых простых и уродливых, но она репрезентативна, как это можно сделать.

Смежные вопросы