【问题标题】:When is new Guid() 00000000-0000-0000-0000-000000000000,when not? [duplicate]什么时候是 new Guid() 00000000-0000-0000-0000-000000000000,什么时候不是? [复制]
【发布时间】:2021-07-29 18:21:58
【问题描述】:

我有一个大型日志 C# 文件。我的客户抱怨说某些 SessionId 是 00000000-0000-0000-0000-000000000000。 第一种方法

public static StartServiceLog CreateStartServiceLog(string serviceName, Guid sessionId = new Guid(), Device device = null, string userId = null)
{
    if (device == null)
    {
        device = CreateDeviceInfo();
    }

    return new StartServiceLog(device, DateTime.UtcNow, sessionId, userId, new List<string>() { serviceName });
}

我调用这个方法

    var session = new StartSessionLog
    {
        Sid = sessionId,
        Device = device,
        Timestamp = DateTime.UtcNow,
    };
    return session;

如何确定 SessionId 何时将全为零或将被覆盖?

【问题讨论】:

  • new Guid() 返回00000000-0000-0000-0000-000000000000,Guid.NewGuid() 生成一个新的随机数
  • Guid 是一个值类型; new AnyValueType()基本上是“用全​​零/空值初始化”;改用Guid.NewGuid()
  • @TimSchmelter 我又添加了几行,看看。

标签: c#


【解决方案1】:

我认为您错误地使用 new Guid() 而不是 Guid.NewGuid() 来生成全新的 Guid。

看这个例子:

Console.WriteLine(new Guid());
Console.WriteLine(Guid.NewGuid());

哪些输出:

00000000-0000-0000-0000-000000000000
1b8640a1-a9d0-42c5-aaff-a87831687792

问题在于Guid.NewGuid() 不能用作参数的默认值,因为它不是编译时常量。

相反,您可以执行以下操作:

public static StartServiceLog CreateStartServiceLog(string serviceName, Guid? sessionId = null, Device device = null, string userId = null)
{
    if (sessionId == null)
        sessionId = Guid.NewGuid();
    ...

sessionId 的默认值设置为NULL,如果是,则在您的方法中正确创建一个新的guid。

【讨论】:

    【解决方案2】:

    new Guid() 不会生成新的Guid,它只会返回全零。改用Guid.NewGuid()(当然不能作为默认值)。

    在可选参数中使用 this 的简单模式如下:

    void DoSomething(Guid? id = default)
    {
      id ??= Guid.NewGuid();
    }
    

    【讨论】:

      【解决方案3】:

      System.Guid 是一个结构,而不是一个类。这意味着它的无参数构造函数不能做任何工作,所以,new Guid() == default

      结构的默认值是所有成员都设置为默认值。在Guid 的情况下,它是一串数字,因此它的视觉表示最终全为零。

      要创建具有实际值的Guid,您需要调用Guid.NewGuid() 静态方法。这不能在默认参数初始化程序中完成,因此您需要更改方法以采用 nullable Guid? 代替:

      public static void Foo(string etcetera, Guid? sessionId = null)
      {
          if (sessionId == null)
          {
              sessionId = Guid.NewGuid();
          }
      
          // Do something with `sessionId.Value`
      }
      

      【讨论】:

      • 奇怪的是,即使默认构造函数 确实 工作(如果你在 IL 中编码),在这种情况下也不会执行,这 真的是 default(Guid) 的情况,它只是初始化为全 0。您可以在 IL on Sharplab 中看到这一点
      • @Charlieface 我对 IL 了解不多,但是在那里为值类型定义默认构造函数是否合法?无论哪种方式,C# 编译器都假定 C# 规则用于可选参数初始化。
      • 在 IL 中没有什么可以阻止你,但是是的,C# 不会执行它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-07
      相关资源
      最近更新 更多