Несколько комментариев:
t.Value = (T)x;
Приведение необходимо.Это потому, что t.Value
имеет тип T
, а x
имеет тип object
.Строго типизированная природа C # требует, чтобы вы сказали компилятору: «Послушайте, я знаю, что это может быть небезопасно, но можете ли вы просто попытаться сделать это для меня в любом случае, путем преобразования или распаковки или чего-то еще? Спасибо!»
2.
object x = null;
if (dictionary.TryGetValue(key, out x)) {
if (x.GetType() == typeof(T)) {
t.Value = (T)x;
t.HasValue = true;
}
}
return t;
Что если x
является экземпляром класса, производного от T
?Или, если x
является экземпляром класса, который реализует интерфейс, и T
это интерфейс?Прямо сейчас вы вернете экземпляр ValueWrapper<T>
, который указывает, что в словаре не было объекта с ключом key
.Я бы сказал, что это очень противоречит тому, что ожидает большинство людей.
Кроме того, если вы не собираетесь вырвать, когда dictionary
не содержит значение, соответствующее ключу key
, я думаю, вам следуетпереименуйте ваш метод в TryGetValue
, примите параметр out
типа ValueWrapper<T>
и верните bool
, указывающий на успех / неудачу.
3.
Отвечая на ваш комментарий,вот одно решение.
public interface IValueWrapper {
object Value { get; set; }
bool HasValue { get; set; }
}
public class ValueWrapper<T> : IValueWrapper {
public T Value { get; set; }
object IValueWrapper.Value {
get { return Value; }
set { this.Value = (T)value; }
}
public bool HasValue { get; set; }
public ValueWrapper() {
this.HasValue = false;
}
public ValueWrapper(T value) {
this.Value = value;
this.HasValue = value != null;
}
}
public static class DictionaryExtensions {
public static void Add<T>(
this IDictionary<string, IValueWrapper> dictionary,
string key,
T value
) {
ValueWrapper<T> valueWrapper = new ValueWrapper<T>(value);
dictionary.Add(key, valueWrapper);
}
public static bool TryGetWrappedValue<T>(
IDictionary<string, IValueWrapper> dictionary,
string key,
out ValueWrapper<T> value
) {
IValueWrapper valueWrapper;
if (dictionary.TryGetValue(key, out valueWrapper)) {
value = (ValueWrapper<T>)valueWrapper;
return true;
}
else {
value = null;
return false;
}
}
}
Использование:
var dict = new Dictionary<string, IValueWrapper>();
dict.Add("hello", 5);
ValueWrapper<int> value;
dict.TryGetWrappedValue("hello", out value);
Вам нужно будет добавить проверку параметров и т. д.