[C#] Null Coalescing 연산자를 사용하는 고유 한 방법

C #에서 Null 통합 연산자를 사용하는 표준 방법은 기본값을 설정하는 것입니다.

string nobody = null;
string somebody = "Bob Saget";
string anybody = "";

anybody = nobody   ?? "Mr. T"; // returns Mr. T
anybody = somebody ?? "Mr. T"; // returns "Bob Saget"

그러나 다른 무엇을 ??사용할 수 있습니까? 다음보다 더 간결하고 읽기 쉬운 것 외에는 삼항 연산자만큼 유용하지 않습니다.

nobody = null;
anybody = nobody == null ? "Bob Saget" : nobody; // returns Bob Saget

따라서 null 병합 연산자에 대한 지식조차도 적습니다 …

  • ??다른 용도로 사용해 보셨습니까 ?

  • ??필요, 또는 당신은 (가장 잘 알고있는 것으로) 삼항 연산자를 사용한다



답변

우선, 표준 삼항보다 체인을 연결하는 것이 훨씬 쉽습니다.

string anybody = parm1 ?? localDefault ?? globalDefault;

vs.

string anyboby = (parm1 != null) ? parm1
               : ((localDefault != null) ? localDefault
               : globalDefault);

null 가능 객체가 변수가 아닌 경우에도 잘 작동합니다.

string anybody = Parameters["Name"]
              ?? Settings["Name"]
              ?? GlobalSetting["Name"];

vs.

string anybody = (Parameters["Name"] != null ? Parameters["Name"]
                 : (Settings["Name"] != null) ? Settings["Name"]
                 :  GlobalSetting["Name"];


답변

나는 그것을 게으른로드 원 라이너로 사용했습니다 :

public MyClass LazyProp
{
    get { return lazyField ?? (lazyField = new MyClass()); }
}

읽을 수 있습니까? 스스로 결정하십시오.


답변

두 가지 “약간 이상한”방법으로 유용하다는 것을 알았습니다.

  • 루틴을 out작성할 때 매개 변수 를 갖는 대안으로 TryParse(예 : 구문 분석에 실패하면 널값을 리턴)
  • 비교를위한 “모름”표현

후자는 조금 더 많은 정보가 필요합니다. 일반적으로 여러 요소가 포함 된 비교를 만들 때는 비교의 첫 번째 부분 (예 : 나이)이 확실한 답을 제공하는지 확인한 다음 첫 번째 부분이 도움이되지 않는 경우에만 다음 부분 (예 : 이름)을 확인해야합니다. null 병합 연산자를 사용하면 순서 또는 평등에 관계없이 매우 간단한 비교를 작성할 수 있습니다. 예를 들어 MiscUtil 에서 두 개의 도우미 클래스 사용 :

public int Compare(Person p1, Person p2)
{
    return PartialComparer.Compare(p1.Age, p2.Age)
        ?? PartialComparer.Compare(p1.Name, p2.Name)
        ?? PartialComparer.Compare(p1.Salary, p2.Salary)
        ?? 0;
}

분명히 MiscUtil에는 ProjectionComparer가 있으며 확장 기능과 함께 이러한 종류의 작업을 훨씬 쉽게 만들 수는 있지만 여전히 깔끔합니다.

Equals를 구현할 때 참조 동등성 (또는 nullity)을 검사하기 위해 동일한 작업을 수행 할 수 있습니다.


답변

또 다른 장점은 삼항 연산자에 이중 평가 또는 임시 변수가 필요하다는 것입니다.

예를 들어 다음을 고려하십시오.

string result = MyMethod() ?? "default value";

삼항 연산자를 사용하면 다음 중 하나가 남습니다.

string result = (MyMethod () != null ? MyMethod () : "default value");

MyMethod를 두 번 호출하거나

string methodResult = MyMethod ();
string result = (methodResult != null ? methodResult : "default value");

어느 쪽이든, null 병합 연산자는 더 깨끗하고 더 효율적이라고 생각합니다.


답변

고려해야 할 또 다른 사항은 통합 연산자는 삼항처럼 속성의 get 메소드를 두 번 호출하지 않는다는 것입니다.

따라서 삼항을 사용해서는 안되는 시나리오가 있습니다.

public class A
{
    var count = 0;
    private int? _prop = null;
    public int? Prop
    {
        get
        {
            ++count;
            return _prop
        }
        set
        {
            _prop = value;
        }
    }
}

사용하는 경우 :

var a = new A();
var b = a.Prop == null ? 0 : a.Prop;

getter가 두 번 호출되고 count변수는 2와 같습니다.

var b = a.Prop ?? 0

count예상대로 변수는 1에 해당 될 것입니다.


답변

??연산자 에게 가장 큰 장점은 nullable 값 형식을 nullable이 아닌 형식으로 쉽게 변환 할 수 있다는 것입니다.

int? test = null;
var result = test ?? 0; // result is int, not int?

Linq 쿼리에서 이것을 자주 사용합니다.

Dictionary<int, int?> PurchaseQuantities;
// PurchaseQuantities populated via ASP .NET MVC form.
var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0);
// totalPurchased is int, not int?


답변

내가 사용 했어 ?? 내 IDataErrorInfo 구현에서 :

public string Error
{
    get
    {
        return this["Name"] ?? this["Address"] ?? this["Phone"];
    }
}

public string this[string columnName]
{
    get { ... }
}

개별 속성이 “오류”상태 인 경우 해당 오류가 발생하고 그렇지 않으면 null이 발생합니다. 정말 잘 작동합니다.