我试图使用泛型隐藏单个扩展方法背后的一整套遗留方法。这些遗留方法都称为GetValidXXX并具有类似的签名(是的,它们应该 out 而不是 ref )。需要保留旧的GetValidXXX以实现向后兼容。
public static T GetAttributeValue<T>(this DbElement element, DbAttribute attribute, T defaultValue)
{
T result = default(T);
if (typeof(T) == typeof(DbAttribute))
{
if (element.GetValidAttribute(attribute, ref result)) return result;
}
else if (typeof(T) == typeof(bool))
{
if (element.GetValidBool(attribute, ref result)) return result;
}
return defaultValue;
}
这不会编译,因为结果与特定GetValidXXX签名中的类型不匹配(返回值是成功/失败)。
bool GetValidAttribute(DbAttribute attribute, ref DbAttribute result)
bool GetValidBool(DbAttribute attribute, ref bool result)
etc
我如何编写这个来实现我的目标,即能够编写如下代码:
string description = element.GetAttributeValue(DbAttributeInstance.DESC, "unset");
bool isWritable = !element.GetAttributeValue(DbAttributeInstance.READONLY, true);
答案 0 :(得分:3)
您不能将T
用于ref参数,因为编译器无法始终保证它将属于这些类型。你必须做这样的事情:
public static T GetAttributeValue<T>(this DbElement element, DbAttribute attribute, T defaultValue)
{
if (typeof(T) == typeof(DbAttribute))
{
var dbAttribute = default(DbAttribute);
if (element.GetValidAttribute(attribute, ref dbAttribute)) return (T)(object)dbAttribute;
}
else if (typeof(T) == typeof(bool))
{
var boolResult = default(bool);
if (element.GetValidBool(attribute, ref boolResult)) return (T)(object)boolResult;
}
return defaultValue;
}
答案 1 :(得分:1)
Convert.ChangeType()
可能对您的情况有用。
可能的用法:
public static T ConvertTypeOrGetDefault<T>(this object value, T defaultValue)
{
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch (Exception ex)
{
return default(T);
}
}
这取决于&#34; hacky&#34;你是否愿意成为。您也可以考虑重新分解,这样您就不必隐藏遗留方法。