[c#] 이것은 ?[]? C #의 구문?

나는 공부하는 동안 대표 추상 클래스가 실제로을 Delegate.cs, 나는 다음과 같은 방법이있는 이해가 안보고

  • 반환 값 ?이 이미 reference ( class ) 유형 이지만 왜 값을 사용합니까?
  • ?[]? 매개 변수에 대한 의미

설명해 주시겠습니까?

public static Delegate? Combine(params Delegate?[]? delegates)
{
    if (delegates == null || delegates.Length == 0)
        return null;

    Delegate? d = delegates[0];
    for (int i = 1; i < delegates.Length; i++)
        d = Combine(d, delegates[i]);

    return d;
}



답변

단계별 설명 :

params Delegate?[] delegates -nullable 배열입니다 Delegate

params Delegate?[]? delegates -전체 배열은 널 입력 가능

각 매개 변수는 유형 Delegate?이고 Delegate?[]?배열 의 색인을 리턴하므로 리턴 유형이 Delegate?그렇지 않으면 컴파일러는 마치 마치 마치 마치 int문자열을 리턴하는 메소드에서 와 같이 오류 를 리턴합니다.

예를 들어 다음 Delegate과 같은 유형 을 반환하도록 코드를 변경할 수 있습니다 .

public static Delegate Combine(params Delegate?[]? delegates)
{
    Delegate defaulDelegate = // someDelegate here
    if (delegates == null || delegates.Length == 0)
        return defaulDelegate;

    Delegate d = delegates[0] ?? defaulDelegate;
    for (int i = 1; i < delegates.Length; i++)
        d = Combine(d, delegates[i]);

    return d;
}


답변

널 입력 가능 참조 유형 은 C # 8.0의 새로운 기능이며 이전에는 존재하지 않았습니다.

문서화 문제이며 컴파일 타임에 경고가 생성되는 방식입니다.

“객체가 객체의 인스턴스로 설정되지 않았습니다”예외는 일반적입니다. 그러나 이것은 런타임 예외이며 컴파일 타임에 부분적으로 이미 발견 될 수 있습니다.

규제 Delegate d를 위해 당신은 항상 전화 할 수 있습니다

 d.Invoke();

즉, 컴파일 타임에 아무 일도 일어나지 않을 수 있습니다. 런타임에 예외가 발생할 수 있습니다.

새로운 Delegate? p이 코드 동안

 p.Invoke();

컴파일러 경고를 생성합니다. CS8602: Dereference of a possibly null reference
당신이 쓰지 않으면 :

 p?.Invoke();

의미하는 것은 null이 아닌 경우에만 호출하십시오.

따라서 변수에 null을 포함하거나 포함하지 않을 수 있음을 문서화하십시오. 조기에 경고를 발생 시키며 null에 대한 여러 테스트를 피할 수 있습니다. 당신은 int와 int에 대해 무엇을 가지고 있습니까?. 당신은 확실히 하나는 null이 아니며 하나를 다른 것으로 변환하는 방법을 알고 있습니다.


답변

C # 8에서는 참조 유형을 명시 적으로 널 입력 가능으로 표시해야합니다.

기본적으로 이러한 유형은 값 유형과 비슷한 null을 포함 할 수 없습니다. 이것은 후드 아래에서 작동하는 방식을 변경하지 않지만 유형 검사기는 수동으로 수행해야합니다.

주어진 코드는 C # 8에서 작동하도록 리팩토링되었지만이 새로운 기능의 이점은 없습니다.

public static Delegate? Combine(params Delegate?[]? delegates)
{
    // ...[]? delegates - is not null-safe, so check for null and emptiness
    if (delegates == null || delegates.Length == 0)
        return null;

    // Delegate? d - is not null-safe too
    Delegate? d = delegates[0];
    for (int i = 1; i < delegates.Length; i++)
        d = Combine(d, delegates[i]);

    return d;
}

다음은이 기능을 활용하는 업데이트 된 코드 (작동하지 않음, 아이디어)의 예입니다. 그것은 널 체크에서 우리를 구하고이 방법을 약간 단순화했습니다.

public static Delegate? Combine(params Delegate[] delegates)
{
    // `...[] delegates` - is null-safe, so just check if array is empty
    if (delegates.Length == 0) return null;

    // `d` - is null-safe too, since we know for sure `delegates` is both not null and not empty
    Delegate d = delegates[0];

    for (int i = 1; i < delegates.Length; i++)
        // then here is a problem if `Combine` returns nullable
        // probably, we can add some null-checks here OR mark `d` as nullable
        d = Combine(d, delegates[i]);

    return d;
}


답변