【问题标题】:Convert Object type to a DateTimeOffset将 Object 类型转换为 DateTimeOffset
【发布时间】:2018-09-17 02:56:44
【问题描述】:

我有一个字符串和对象的字典,我可以使用整数部分 Convert.ToInt32() ,但是对于 DateTimeOffset,我似乎找不到任何东西(有 Convert.ToDateTime() 但我担心 Offset 部分会被修剪),我尝试搜索 stackoverflow 和 web 但什么都不能使用.

请帮忙。

更新:

我如何初始化 Dictionary 和 Watch 窗口结果。 StoreID 是 int,另一个是 DateTimeOffset。

【问题讨论】:

  • 你试过 DateTimeOffset.Parse() 吗?
  • @DCCoder 我试试看,但是对象需要先用.ToString()转换,不知道有没有办法直接把对象类型转换为DateTimeOffset类型。谢谢你的建议。
  • 您可以使用 DateTimeOffset.Parse() 或者如果对象最初是 DateTimeOffset 则将其转换为该对象。
  • @DCCoder 我已经尝试过类型转换,比如 DateTimeOffset a = (DateTimeOffset) obj;但我得到 Specified cast is not valid 错误。
  • 你能说明你是如何将数据输入字典的吗?

标签: c# object type-conversion


【解决方案1】:

首先,我认为像这样存储多种类型的数据可能是一个坏主意 - 请参阅下面的替代方案。 C# 是强类型的(在大多数情况下),并且当它提前知道类型发生了什么时效果最好。但它确实有办法确定 object 中实际存储的类型,并让您转换回正确的类型引用。

在这种情况下,最适合您的问题的似乎是is operator。这将让您测试object(或引用,或...)是否与指定类型兼容:

object val = task.Data["StartDate"];
if (val is DateTimeOffset)
{
    var dto = (DateTimeOffset)val;
    // do something with the DateTimeOffset
}

在 C# 版本 7 中,他们引入了一种模式匹配变体,可让您缩写类型转换:

object val = task.Data["StartDate"];
if (val is DateTimeOffset dto)
{
    // do something
}

这适用于引用类型和值类型,并将传递任何有效的非转换类型转换。在泛型代码中测试类型的接口也很方便:

if (someobject is IDisposable disp)
{
    disp.Dispose();
}

一般来说,尽管我会尽可能避免使用您的对象字典。虽然在某些情况下它是有效的,但这些情况相当罕见。例如,ASP.NET MVC 中的 ViewBag 是一种可行的情况,但还有其他方法可以做到。

原因很简单:boxing and unboxing values takes time。测试值的类型需要时间,如果您使用静态类型,您通常不需要浪费这些时间。而且您不必担心有人将字符串粘贴到您期望 int 的位置。

对于您自己的代码,更正常的情况是定义一个类来保存任务数据并传递它:

public class TaskData
{
    public int StoreID { get; set; }
    public DateTimeOffset StartDate { get; set; }
}

...并将其用作:

task.Data = new TaskData { StoreID = storeID, startDate = DateTimeOffset.Now.AddDays(3) };

现在您的任务将直接知道它正在处理什么,无需强制转换。并且不可能有人会出现并分配一些您的代码不知道如何处理的古怪值到您的变量之一中。或者忘记使用DateTimeOffset 并改用DateTime,编译器完全不会抱怨。

如果您真的不想为这类事情定义各种类,您可以使用 C#7 Tuple 类型来做类似的事情:

// in your task class:
public (int StoreID, DateTimeOffset StartDate) Data { get; set; }

// initialize in other code:
task.Data = (storeID, DateTimeOffset.Now.AddDays(3));

在上面的类型中,类型是在编译时定义的,带有名称的修饰,这样你就可以在代码的其他地方使用它们,但它们是编译器使用的有效语法糖,在运行时不能通过反射等使用。可以将其视为简化某些事情的方便快捷方式。

当然,如果您确实需要为此数据使用 Dictionary<string, object>,那么请继续。问问自己这些开销是否值得付出努力。

【讨论】:

    猜你喜欢
    • 2018-11-12
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2021-04-25
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多