source

Nullable 간의 차이점은 무엇입니까?값 또는 Null 가능!=이(가) null입니까?

manysource 2023. 5. 20. 10:55

Nullable 간의 차이점은 무엇입니까?값 또는 Null 가능!=이(가) null입니까?

항상 사용했습니다.Nullable<>.HasValue의미론이 좋았기 때문입니다.에 저는 에서 하만지, 최에나다른사람기의존코드는사그용들을 사용하는 작업을 .Nullable<> != null그 대신 독점적으로

하나를 다른 하나보다 사용하는 이유가 있나요, 아니면 순전히 선호하는 이유인가요?

  1. int? a;
    if (a.HasValue)
        // ...
    

대.

  1. int? b;
    if (b != null)
        // ...
    

가 컴러가대다니체합파를 합니다.null에대 의비교과출에 대한 HasValue그래서 실질적인 차이는 없습니다.여러분과 여러분의 동료들에게 더 읽기 쉬운 것을 하세요.

선호합니다(a != null)구문이 참조 유형과 일치하도록 합니다.

저는 nullable int에 값을 할당하기 위해 다른 방법을 사용하여 이에 대한 연구를 수행했습니다.제가 여러 가지 일을 했을 때의 일입니다.무슨 일이 일어나고 있는지 분명히 해야 합니다. 명할사항:Nullable<something> 줄여서 는또속기속.something?컴파일러가 null을 클래스처럼 사용할 수 있도록 하기 위해 많은 작업을 수행하는 것으로 보이는 구조입니다.
보시는 처럼, 에보시바와같이는아래,같이,SomeNullable == null그리고.SomeNullable.HasValue항상 true 또는 false를 반환합니다., 아에설명않는았만지지되래,,SomeNullable == 3이 ""(SomeNullable)이라고할 때도합니다.int?).
하는 동안에SomeNullable.Value할당한 경우 런타임 오류가 발생합니다.nullSomeNullable 연산자, 연산자, 오버로드 연산자의 조합으로 가 우리에게 수 입니다.object.Equals(obj)메소드, 컴파일러 최적화 및 원숭이 비즈니스.

다음은 실행된 일부 코드와 레이블로 생성된 출력에 대한 설명입니다.

int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")

좋아요. 다음 초기화 방법을 시도해 보겠습니다.

int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")

모두 예전과 같습니다.다을사용초여다니합으로 초기화한다는 하세요.int? val = new int?(null);, 시간 했을 수 . null은 null과 null의 관계가 있습니다.래퍼 개체 자체만 null과 같을 수 있습니다.

마찬가지로 컴파일 시간 오류가 발생할 수 있습니다.

int? val = new int?();
val.Value = null;

val.Value어차피 읽기 전용 속성이기 때문에 다음과 같은 것은 사용할 수 없습니다.

val.Value = 3;

그러나 다시, 다형 오버로드 암시적 변환 연산자를 사용하면 다음과 같이 할 수 있습니다.

val = 3;

하지만 카마가 어떤 것을 부르는지에 대해서는 걱정할 필요가 없습니다. 제대로 작동하는 한요?:)

에서는 VB를 사용하지 .Net에서 사용 안 함IsNot Nothing를 사용할 수 때..HasValue 를 " 방금작이런타만수있들음게중다간신오"로 했습니다.IsNot Nothing와 함께.HasValue한 자리에왜 그런지는 잘 모르겠지만 컴파일러에서 뭔가 다르게 일어나고 있습니다.라고 추측하건대!= nullC#에서 동일한 문제가 발생할 수 있습니다.

만약 당신이 linq를 사용하고 코드를 짧게 유지하고 싶다면, 나는 항상 사용하는 것을 추천합니다.!=null

이것이 바로 이유입니다.

우리가 수업을 한다고 상상해 보세요.Foo무효 이중 변수가 있는 경우SomeDouble

public class Foo
{
    public double? SomeDouble;
    //some other properties
}   

만약 우리 코드의 어딘가에서 우리가 Foo 컬렉션에서 null이 아닌 SomeDouble 값을 가진 모든 Foo를 얻고 싶다면, 우리는 함수를 쓰는 적어도 세 가지 방법을 갖게 됩니다(C#6을 사용하는 경우).

public IEnumerable<Foo> GetNonNullFoosWithSomeDoubleValues(IEnumerable<Foo> foos)
{
     return foos.Where(foo => foo?.SomeDouble != null);
     return foos.Where(foo=>foo?.SomeDouble.HasValue); // compile time error
     return foos.Where(foo=>foo?.SomeDouble.HasValue == true); 
     return foos.Where(foo=>foo != null && foo.SomeDouble.HasValue); //if we don't use C#6
}

그리고 이런 상황에서 저는 항상 짧은 것을 추천합니다.

두 번째 방법은 몇 배 더 효과적일 것입니다(대부분 안감과 복싱의 컴파일러 때문이지만 여전히 숫자는 매우 표현적입니다).

public static bool CheckObjectImpl(object o)
{
    return o != null;
}

public static bool CheckNullableImpl<T>(T? o) where T: struct
{
    return o.HasValue;
}

벤치마크 테스트:

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1648.0
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1648.0
  Core   : .NET Core 4.6.25009.03, 64bit RyuJIT


        Method |  Job | Runtime |       Mean |     Error |    StdDev |        Min |        Max |     Median | Rank |  Gen 0 | Allocated |
-------------- |----- |-------- |-----------:|----------:|----------:|-----------:|-----------:|-----------:|-----:|-------:|----------:|
   CheckObject |  Clr |     Clr | 80.6416 ns | 1.1983 ns | 1.0622 ns | 79.5528 ns | 83.0417 ns | 80.1797 ns |    3 | 0.0060 |      24 B |
 CheckNullable |  Clr |     Clr |  0.0029 ns | 0.0088 ns | 0.0082 ns |  0.0000 ns |  0.0315 ns |  0.0000 ns |    1 |      - |       0 B |
   CheckObject | Core |    Core | 77.2614 ns | 0.5703 ns | 0.4763 ns | 76.4205 ns | 77.9400 ns | 77.3586 ns |    2 | 0.0060 |      24 B |
 CheckNullable | Core |    Core |  0.0007 ns | 0.0021 ns | 0.0016 ns |  0.0000 ns |  0.0054 ns |  0.0000 ns |    1 |      - |       0 B |

벤치마크 코드:

public class BenchmarkNullableCheck
{
    static int? x = (new Random()).Next();

    public static bool CheckObjectImpl(object o)
    {
        return o != null;
    }

    public static bool CheckNullableImpl<T>(T? o) where T: struct
    {
        return o.HasValue;
    }

    [Benchmark]
    public bool CheckObject()
    {
        return CheckObjectImpl(x);
    }

    [Benchmark]
    public bool CheckNullable()
    {
        return CheckNullableImpl(x);
    }
}

https://github.com/dotnet/BenchmarkDotNet 이 사용되었습니다.

따라서 다음과 다른 파이프라인에서 Nullable을 처리할 수 있는 옵션(예: 사용자 지정 직렬화기 작성)이 있는 경우object특정 속성을 사용합니다. 수행하고 Nullable 특정 속성을 사용합니다.그래서 일관된 사고의 관점에서.HasValue선호되어야 합니다.일관된 생각을 통해 코드를 더 잘 작성할 수 있습니다. 세부 사항에 너무 많은 시간을 할애하지 마십시오.

PS. 사람들은 "일관적인 사고 때문에 가치가 있는 것을 선호한다"는 조언은 관련이 없고 쓸모가 없다고 말합니다.이것의 성능을 예측할 수 있습니까?

public static bool CheckNullableGenericImpl<T>(T? t) where T: struct
{
    return t != null; // or t.HasValue?
}

PPS 사람들은 계속 마이너스입니다, 아무도 성과를 예측하려고 하지 않는 것 같습니다.CheckNullableGenericImpl제가 말씀드리겠습니다: 컴파일러는 당신이 교체하는 것을 도와주지 않을 것입니다.!=null와 함께HasValue.HasValue성능에 관심이 있는 경우 직접 사용해야 합니다.

언급URL : https://stackoverflow.com/questions/676078/what-is-the-difference-between-nullablet-hasvalue-or-nullablet-null