使用泛型从对象获取基本类型

时间:2016-02-19 08:01:19

标签: c# entity-framework

我需要将键值对存储在数据库中。值可以是以下类型之一:boolintdoublestringDateTime。在Set<T>下面的班级中,操作有效,但Get<T>会引发InvalidCastException

public class PersistedKeyValueStorage
{
    AppDbContext _dbContext;
    public PersistedKeyValueStorage() : this(new AppDbContext()) { }
    public PersistedKeyValueStorage(AppDbContext dbContext)
    {
        _dbContext = dbContext; 
    }

    public T Get<T>(string Key) {
        var record=_dbContext.Set<StoredKeyValueItem>().FirstOrDefault(p => p.Key == Key);

        if (record != null) return (T)(object)(record.Value); // here is error
            return default(T);                
    }

    public void Set<T>(string Key, T Value) where T : struct            
    {
        var record = _dbContext.Set<StoredKeyValueItem>().FirstOrDefault(p => p.Key == Key);
        if (record != null) record.Value = Value.ToString();

        else _dbContext.Set<StoredKeyValueItem>().Add(new StoredKeyValueItem { Key = Key, Value = Value.ToString() });

        _dbContext.SaveChanges();
    }
}
// class usage

var skvs = new PersistedKeyValueStorage();
skvs.Set("test.int", (int)123);
skvs.Set("test.boolean", true);
skvs.Set("test.datetime", DateTime.Now);

ViewBag.testint= skvs.Get<int>("test.int");
ViewBag.testbool = skvs.Get<Boolean>("test.boolean");
ViewBag.testdate= skvs.Get<DateTime>("test.datetime");

1 个答案:

答案 0 :(得分:1)

您将所有值存储为商店中的字符串。

所以当你把它们拿回来时,它们就会成为弦乐。

要从object转到T,那么实际的对象必须是:

  • 类型T
  • 的值类型
  • 可以重新解释为T
  • 的引用类型

int是值类型,但在执行(int)obj时,您只能取消内部的值,而且必须是int。在您的情况下,它是string。这不会奏效。

相反,在这种情况下,您必须使用转换层与您的存储类型string进行转换。

对于某些类型,您可以尝试将代码更改为:

return (T)Convert.ChangeType(record.Value, typeof(T));

但是,这不会处理所有符合T条件的类型。