我正在尝试使用泛型编写以下方法。 (我的实际方法比这更复杂。)
public T ParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary)
{
T result;
if (dictionary.TryGetValue(s, out result))
return result;
// TODO: Return special value such as null to indicate invalid item
}
如果项目不在词典中,我的目标是返回null
之类的内容。
问题是我不知道T
是什么类型。例如,如果T
是一个整数,那么我应该返回类型T?
。但是,如果T
是一个类,那么它已经可以为空了。直到运行时我才会知道这一点。
任何人都可以看到一种干净的方法来返回此方法中的特殊值以指示该项无效吗?我愿意返回null
之外的其他内容,但它必须是一个特殊值。 (0不是整数的特殊值。)
答案 0 :(得分:11)
我建议返回ParseResult<T>
,其定义如下:
public struct ParseResult<T>
{
// Or an exception, or a way of creating an exception
private readonly bool success;
private readonly T value;
// Accessors etc
}
这样你就不必担心可空性,而且你可以非常清楚你正在做什么。这是我在Noda Time中使用的模式,在我看来它的效果非常好。 (目前我们使用的是类而不是结构,但我可能会改变它......)
我更喜欢其他方法,因为:
out
参数T
是引用类型还是值类型null
成功解析价值的情况答案 1 :(得分:5)
也许两个重载会有所帮助:
public T? ParseStructDictionaryItem<T>(string s, Dictionary<string, T> dictionary) where T : struct
{
T result;
if (dictionary.TryGetValue(s, out result))
return result;
return null;
}
public T ParseReferenceDictionaryItem<T>(string s, Dictionary<string, T> dictionary) where T : class
{
T result;
if (dictionary.TryGetValue(s, out result))
return result;
return default(T);
}
答案 2 :(得分:4)
您可以为值类型创建两个方法,为引用类型创建另一个方法。
值类型方法将返回T?
而不是T
。在这两种方法中,您都可以返回null
来表示无效值。
public T? ParseDictionaryItemValueType<T>(string s, Dictionary<string, T> dictionary)
where T : struct
{
T result;
if (dictionary.TryGetValue(s, out result))
return result;
return null;
}
public T ParseDictionaryItemReferenceType<T>(string s, Dictionary<string, T> dictionary)
where T : class
{
T result;
dictionary.TryGetValue(s, out result);
return result;
}
答案 3 :(得分:0)
为什么重新发明轮子?看看你自己的代码:
您正在使用Dictionary的TryGetValue
方法。它如何处理同样的问题?
我建议你跟随.Net Framework开发人员的脚步并做同样的事情:
public bool TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out T result)
{
if (dictionary.TryGetValue(s, out result)) {
return true;
}
return false;
}
<强>更新强>
既然你不喜欢这种方法,那怎么样就把它转过头来?
public T TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out bool Success)
{
T result = default(T);
Success = (dictionary.TryGetValue(s, out result))
return result;
}