将对象类型转换为DateTimeOffset

问题描述 投票:-1回答:1

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

请帮忙。

更新:

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

enter image description here

c# object type-conversion
1个回答
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>来获取这些数据,那就继续吧。只要问问自己,开销是否值得付出努力。

© www.soinside.com 2019 - 2024. All rights reserved.