我知道C#不支持带有参数的属性,但默认属性除外。但我认为在某些情况下拥有这样的功能仍然很好。例如,应用程序可能具有特定于当前使用的语言的设置。所以这样的设置属性可能看起来像这样。
settings.IsContentDownloaded["en-US"] = true;
事件认为默认情况下不支持此功能,我们可以提供一种解决方法,使用该语言中提供的其他强大功能来模拟此功能。但问题是什么是提供这个问题的通用方法的最佳解决方法。
我有自己的解决方法,我已将其作为答案分享。但我正在寻找一种更好的方法或改进我的方法。
答案 0 :(得分:1)
创建一个字典,其中键是您的字符串,例如" en-US"而值是一个布尔:
Dictionary<string, bool> aaa = new Dictionary<string, bool>();
aaa.Add("en-US", true);
if(aaa["en-US"].Equals(true))
{
}
答案 1 :(得分:1)
这是一个有趣的问题,这是我提出的方法:
public class LocalizableSetting<T> : IEnumerable<KeyValuePair<string, T>>
{
private Dictionary<string, T> _values;
public T this[string cultureName]
{
get { return _values[cultureName]; }
set
{
_values[cultureName] = value;
}
}
public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
{
return _values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _values.GetEnumerator();
}
public static implicit operator T(LocalizableSetting<T> value)
{
return value[CultureInfo.CurrentCulture.Name];
}
public static implicit operator LocalizableSetting<T>(T value)
{
var setting = new LocalizableSetting<T>();
setting[CultureInfo.CurrentCulture.Name] = value;
return setting;
}
}
这里LocalizableSetting
将本地化值存储在内部字典中,这实际上并不特别,但是我添加了一个允许它像普通属性一样使用的功能,即隐式转换运算符。
这确实需要使用一些技巧,为了在类中正确使用它,你不能使用自动属性,因为你必须在一个集合上合并它们,而不是覆盖它,以下是如何在类中使用它的示例:
public class SomeLocalizableClass
{
//Explicitly declare the backing field for the property!
private LocalizableSetting<int> _intSetting = new LocalizableSetting<int>();
public LocalizableSetting<int> IntSetting
{
get { return _intSetting; }
set
{
//Merge, don't overwrite
foreach (var kvp in value)
_intSetting[kvp.Key] = kvp.Value;
}
}
}
请注意,在set
方法中,它遍历值并覆盖当前值或添加新值(在索引器的帮助下)。
所以,这可以让你做这样的事情:
public class SomeConsumerClass
{
public void SomeMethod()
{
SomeLocalizableClass c = new SomeLocalizableClass();
c.IntSetting["fr-FR"] = 4; //Sets the french setting
c.IntSetting = 10; //Sets the current culture setting
int multipleSetting = c.IntSetting * c.IntSetting;
}
}
由于从multipleSetting
到LocalizableSetting<int>
的隐式转换,int
将是该属性的当前文化值的倍数。 c.IntSetting = 10
导致从源类型(int
)到LocalizableSetting<int>
的隐式转换,然后将其分配给属性,这就是需要合并而不是覆盖的原因。
我留下了几个(大)漏洞,即如果找不到该文化的值,属性应该返回一些默认值(目前它会抛出异常)。但它显示了一种解决这个问题的方法。
答案 2 :(得分:0)
我使用了名为_settingsRepositoty
的字典来存储设置,但它可能是用于根据应用程序类型存储设置的任何内容。
public class Settings
{
private Dictionary<string, object> _settingsRepository = new Dictionary<string, object>();
private LanguageSpecificPropertyFactory _factory;
public Settings()
{
_factory = new LanguageSpecificPropertyFactory(this);
}
public LanguageSpecificProperty<bool> IsContentDownloaded
{
get
{
return _factory.GetLanguageProperty("IsContentDownloaded", false);
}
}
private void Set<T>(string propertyName, string lang, T val)
{
string fullPropertyName = string.Format("{0}_{1}", propertyName, lang);
_settingsRepository[fullPropertyName] = val;
}
private T Get<T>(string propertyName, string lang, T defaultValue)
{
string fullPropertyName = string.Format("{0}_{1}", propertyName, lang);
if (!_settingsRepository.ContainsKey(fullPropertyName))
{
_settingsRepository[fullPropertyName] = defaultValue;
}
return (T)_settingsRepository[fullPropertyName];
}
public class LanguageSpecificProperty<T>
{
private string _properyName;
private T _defaultValue;
private Settings _settings;
internal LanguageSpecificProperty(Settings settings, string propertyName, T defaultValue)
{
_properyName = propertyName;
_defaultValue = defaultValue;
}
public T this[string lang]
{
get
{
return _settings.Get<T>(_properyName, lang, _defaultValue);
}
set
{
_settings.Set<T>(_properyName, lang, value);
}
}
}
public class LanguageSpecificPropertyFactory
{
private Dictionary<string, object> _properties = new Dictionary<string, object>();
private Settings _settings;
public LanguageSpecificPropertyFactory(Settings settings)
{
_settings = settings;
}
internal LanguageSpecificProperty<T> GetLanguageProperty<T>(string propertyName, T defaultValue)
{
if (!_properties.ContainsKey(propertyName))
{
_properties.Add(propertyName, new LanguageSpecificProperty<T>(_settings, propertyName, defaultValue));
}
return (LanguageSpecificProperty<T>)_properties[propertyName];
}
}
}