Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该公开一个可空字段还是一个HasFoo字段?_C# - Fatal编程技术网

C# 我应该公开一个可空字段还是一个HasFoo字段?

C# 我应该公开一个可空字段还是一个HasFoo字段?,c#,C#,我正在从XML格式中读取一些数据并将其放入我的类中,我只是想知道,对于可以为空的字段(如果为空,则具有默认值),最好的做法是什么。未提供的值不需要写回文件 我曾考虑使用可空类型,但是,在代码中指定默认值的最佳方式是什么(尽管我不需要为每个字段都指定默认值,因为并非所有字段都有指定的默认值,或者默认值为0) 目前我正在使用这个: class SomeElement { public const int DefaultFoo = 123; public int? Foo { get

我正在从XML格式中读取一些数据并将其放入我的类中,我只是想知道,对于可以为空的字段(如果为空,则具有默认值),最好的做法是什么。未提供的值不需要写回文件

我曾考虑使用可空类型,但是,在代码中指定默认值的最佳方式是什么(尽管我不需要为每个字段都指定默认值,因为并非所有字段都有指定的默认值,或者默认值为0)

目前我正在使用这个:

class SomeElement
{
    public const int DefaultFoo = 123;

    public int? Foo { get; set; }
}
但不知道以下情况是否会更明显:

class SomeElement
{
    // Setting HasFoo to false will set Foo to the default value
    public bool HasFoo { get; set; }
    // Setting Foo to anything will set HasFoo to true
    public int Foo { get; set; }
}
由于一些类有很多属性,第二个选项将在类中创建更多的方法,但是,如果您不关心Foo是否有值,那么使用起来可能会更容易

最后一种选择可能是在基类中使用一个静态方法,或者使用一个扩展方法,以使默认值更容易获得(基于idea)

我仍然会提供
DefaultFoo
字段,但是静态/扩展方法可能会更容易访问


你的想法是什么?以前有人遇到过这个问题吗?我是否应该只使用默认值,并在保存回文件时忽略与其默认值相等的字段?

我认为可以为空的字段更可取。没有多余的代码使它们在文件中保持同步,意图非常明确,您可以访问Foo.HasValue,在我看来,它比类上单独的HasValue属性更好地表达您的意图。

对于没有默认值的值,我将使用空值的组合,以及为具有默认值的值重写默认getter(假设您实际上不需要知道所获取的值是否为默认值):


在这两种情况下仍然返回null值,以保持一致性,并隐藏具有默认值的属性与不具有调用代码的属性之间的任何差异(这样,您可以轻松更改类中哪些值具有默认值或不具有默认值,而不影响使用该类的代码).

是否需要公开非valuetype对象?(即引用)?一些元素将是字符串,但没有一个是自定义类。我也更喜欢带有空值的版本。如果另一个用户只是懒洋洋地检查类,那么他最终会读取错误的值,因为他访问value属性时没有检查状态。我同意。通过使用
Nullable
,定义被紧密地包含,您立即知道它可能为null。如果你使用两种方法,理解之间的距离会增加,这会导致混淆。谢谢,你对混淆的观点很好。默认值呢?康斯特球场是最好的去处吗?我猜在代码中你可以有:myObj.Foo??SomeElement.DefaultFoo
// In some method using the class
int value = SomeElementBase.GetValueOrDefault(() => myObj.Foo);
// or an extension method
int value = myObj.GetValueOrDefault(x => x.Foo);
class SomeElement {
   public int? NoDefault {
      get; set;
   }

   private int? m_hasDefault;
   public int? HasDefault {
      set { m_hasDefault = value; }
      get {
         if(m_hasDefault.HasValue)
            return m_hasDefault;
         else
            return WhateverTheDefaultShouldBe;
      }
   }
}