在WinRT中,设置存储为对象,这意味着您最终会进行大量的转换以恢复所需的类型。由于这似乎是为什么将泛型添加到C#的原因之一,我一直试图简化我的代码,以便我可以做类似的事情:
public string LastRunVersion
{
get
{
return GetLocalSettingsValue<String>("LastRunVersion", null);
}
set
{
SetLocalSettingsValue("LastRunVersion", value);
}
}
我遇到的问题是SetLocalSettingsValue的签名。我试过了:
private T GetLocalSettingsValue<T>(string tag, T defaultValue) where T:Object
但不允许使用对象,因为它不是有效约束。我知道我只存储布尔和字符串,所以我尝试了:
private T GetLocalSettingsValue<T>(string tag, T defaultValue) where T:String, bool
但是编译器说&#34;用作约束的类型必须是接口,非密封类或类型参数&#34;。
我需要对定义做什么才能让我使用string和bool?
感谢。
答案 0 :(得分:1)
正如Sriram所暗示的,实施两种不同的方法似乎是最直接关注的最简单的解决方案。也就是说,您的通用方法是可行的,具有先例,并且将来可以更容易地扩展代码。
事实上,你所尝试的几乎是正确的。主要的是你根本不需要约束。没有它的方法声明很好,虽然你没有显示方法体,但只要你需要做的就是将一些对象引用转换为类型T
,这将起作用:
private T GetLocalSettingsValue<T>(string tag, T defaultValue)
{
object value;
// initialize/retrieve the value somehow
// Check for value present, return default if missing, cast otherwise
return value != null ? (T)value : defaultValue;
}
实际上,由于您传递的是默认值,因此在某些情况下,类型推断将允许您省略type参数。例如:
public string LastRunVersion
{
get { return GetLocalSettingsValue("LastRunVersion", (string)null); }
}
如果你有一个非空的默认值,上面会更有趣。 :)使用null值,您必须将其强制转换为string
,以便编译器知道正确的类型是什么,这与提供类型参数几乎相同。但是,如果您传递string
字面值或string
变量的值,则类型将是明确的,并且根本不需要提供类型的名称(甚至不作为强制转换)
更有趣的是bool
场景:
public string LastRunVersion
{
get { return GetLocalSettingsValue("SomeBooleanSetting", false); }
}
此处,文字具有清晰类型,因此您无需以任何形式提供类型名称。
最后,请注意C#确实对类型的default
值有所了解。如果要支持非null,非零默认值,那么您当前的方法是好的。但是,如果您的默认值始终是null
,false
或0
(例如int
,那么您是否需要存储类似的内容) ,那么你根本不需要默认参数:
private T GetLocalSettingsValue<T>(string tag)
{
object value;
// initialize/retrieve the value somehow
// Check for value present, return default if missing, cast otherwise
return value != null ? (T)value : default(T);
}
任何引用类型都将使用null
作为默认值。对于值类型,如果使用无参数构造函数创建实例,则将获得任何值(所有值类型都具有无参数构造函数)。数字类型的默认值均为0,bool
默认为false
等。
当然,在这种情况下,您将始终必须提供type参数,因为没有任何参数可以从中推断出类型参数。