如何使用C#generics简化对WinRT设置的访问?

时间:2015-01-07 15:49:12

标签: c# generics

在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?

感谢。

1 个答案:

答案 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,非零默认值,那么您当前的方法是好的。但是,如果您的默认值始终是nullfalse0(例如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参数,因为没有任何参数可以从中推断出类型参数。