【问题标题】:C# Hide member in same Namespace and ClassC#隐藏相同命名空间和类中的成员
【发布时间】:2019-11-30 21:30:18
【问题描述】:

似乎在 C# 中无法为应用程序设置时区,所以我想将 DateTime.Now 更改为我在无法更改的 UTC 上运行的机器上的时区。 我想使用 System 命名空间来隐藏 DateTime.Now,因为这样我就不会犯使用错误的 DateTime.Now 的错误,因为它会被隐藏。这就是我想要实现的目标:

namespace System
{
    public static class DateTime
    {
        public new static DateTime Now => System.DateTime.UtcNow.AddHours(1);
    }
}

但它不起作用,因为:

“...DateTime.cs”中的“DateTime”类型与导入的冲突 在“System.Runtime”中输入“DateTime”。

有没有办法做这样的事情?

编辑: 我想知道是否可以“覆盖” System.DateTime,如果可以,该怎么做。

【问题讨论】:

  • It seems like in C# it is not possible to set the timezone for a Application 请详细说明。你可能建立在一个错误的前提下你的推理。
  • 我发现了这个:stackoverflow.com/a/33869808/8529170,但这不适用于整个应用程序,许多线程仅适用于当前线程。但我发现只有人写它是不可能从完整的应用程序。
  • 不,我想“覆盖” System.DateTime。现在,问题的标题是正确的,但没有一个答案能满足您的链接问题所要求的,或者能满足我的要求
  • @MichaelSantos 我认为您正在尝试解决错误的问题。如果您需要应用程序的某些方面可以跨时区移植,那么您应该始终使用 UTC 时间。您可以根据需要将 UTC 时间转换为本地时间。如果您想避免使用错误的时间方法,请为您的所有日期处理代码编写单元测试

标签: c#


【解决方案1】:

不要“覆盖”System.DateTime,而是用自己的类包装它并在任何地方使用它

public class ApplicationTime
{
    private readonly int _offset;

    public DateTime Now => System.DateTime.UtcNow.AddHours(offset);

    public ApplicationTime(int hoursOffset) => _offset = hoursOffset;
}

用法

var applicationTime = new ApplicationTime(1);

var delivery = new Delivery
{
    CreatedAt = applicationTime.Now
};

技术上可以“覆盖”DateTime.Now
但我不建议在实际应用中使用它,尤其是在您的朋友开发人员阅读和使用您的代码时;) p>

如果您使用using 指令的默认位置(位于文件顶部)并且您没有使用DateTime 类型的全名,则可以这样做。 (不是这个:System.DateTime.Now

using System;

namespace Business
{
    public class Dispatching
    {
        public string Send(string delivery)
        {
            return $"Delivery '{delivery}' sent at {DateTime.Now:dd-MM-yyyy HH:mm}";
        }
    }
}

由于using DateTime; 位于命名空间之外,编译器将首先从Business 命名空间中查找DateTime 类型,如果找不到,将检查导入的命名空间。
所以我们可以利用这一点,在Business命名空间中引入我们自己的DateTime实现。

namespace Business
{
    public class DateTime
    {
        public static System.DateTime Now => System.DateTime.UtcNow.AddHours(1);
    }
}

然后

var output = new Dispatching.Send("to destination");
Console.WriteLine(output);

// Delivery 'to destination' sent at 01-12-2019 03:10:49
// UTC time + 1 hour

如果我们将using 指令放在命名空间中,我们的“覆盖”将被忽略。

namespace Business
{
    using System;

    public class Dispatching
    {
        public string Send(string delivery)
        {
            return $"Delivery '{delivery}' sent at {DateTime.Now:dd-MM-yyyy HH:mm}";
        }
    }
}

【讨论】:

  • "overriding" System.DateTime 正是我想要的,我想知道它是否可能,如果是的话如何
  • 是的,这是可能的,但有一些限制,这产生的问题多于好处
  • @MichaelSantos,检查更新,回答,但我不建议使用这种方法,这只是滥用编译器查找逻辑并使您的同事工作/生活困难。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多