Programing

C # if-null-then-null 식

lottogame 2021. 1. 8. 07:45
반응형

C # if-null-then-null 식


호기심 / 편리함을 위해 : C #은 내가 아는 두 가지 멋진 조건식 기능을 제공합니다.

string trimmed = (input == null) ? null : input.Trim();

string trimmed = (input ?? "").Trim();

나는 자주 직면하는 상황에 대한 또 다른 표현이 그리워요.

입력 참조가 널이면 출력은 널이어야합니다. 그렇지 않으면 출력은 입력 개체의 메서드 또는 속성에 액세스 한 결과 여야합니다.

나는 첫 번째 예제에서 정확히 그것을 수행했지만 (input == null) ? null : input.Trim()매우 장황하고 읽을 수 없습니다.

이 경우에 다른 조건식이 ??있습니까? 아니면 연산자를 우아하게 사용할 수 있습니까?


Groovy의 null-safe 역 참조 연산자와 같은 것입니까?

string zipCode = customer?.Address?.ZipCode;

나는 C # 팀이 이것을 보았고 예상했던 것만 큼 우아하게 디자인하는 것이 간단하지 않다는 것을 알았다. 문제의 세부 사항에 대해서는 듣지 못했지만.

나는 현재 언어에 그런 것이 있다고 믿지 않는다. 나는 두려워한다. 그리고 나는 그것에 대한 어떤 계획도 들어 본 적이 없다. 비록 그것이 어떤 시점에서 그것이 일어나지 않을 것이라고 말하는 것은 아니지만.

편집 : 이제 "null 조건부 연산자"로 C # 6의 일부가 될 것입니다.


http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/에 설명 된대로 사용자 지정 Nullify클래스 또는 NullSafe확장 메서드 중에서 선택할 수 있습니다 .

사용법은 다음과 같습니다.

//Groovy:
bossName = Employee?.Supervisor?.Manager?.Boss?.Name

//C# Option 1:
bossName = Nullify.Get(Employee, e => e.Supervisor, s => s.Manager,
                       m => m.Boss, b => b.Name);
//C# Option 2:
bossName = Employee.NullSafe( e => e.Supervisor ).NullSafe( s => s.Boss )
                      .NullSafe( b => b.Name );

현재는 반복하고 싶지 않은 경우에만 확장 메서드를 작성할 수 있습니다.

public static string NullableTrim(this string s)
{
   return s == null ? null : s.Trim();
}

해결책으로 Maybe 모나드를 기반으로하는 이것을 사용할 수 있습니다 .

public static Tout IfNotNull<Tin, Tout>(this Tin instance, Func<Tin, Tout> Output)
{
    if (instance == null)
        return default(Tout);
    else
        return Output(instance);
}

다음과 같이 사용하십시오.

int result = objectInstance.IfNotNull(r => 5);
var result = objectInstance.IfNotNull(r => r.DoSomething());

기본 제공되는 것은 없지만 원하는 경우 확장 메서드로 모든 것을 래핑 할 수 있습니다 (아마도 신경 쓰지 않을 것입니다).

이 특정 예의 경우 :

string trimmed = input.NullSafeTrim();

// ...

public static class StringExtensions
{
    public static string NullSafeTrim(this string source)
    {
        if (source == null)
            return source;    // or return an empty string if you prefer

        return source.Trim();
    }
}

또는보다 범용적인 버전 :

string trimmed = input.IfNotNull(s => s.Trim());

// ...

public static class YourExtensions
{
    public static TResult IfNotNull<TSource, TResult>(
        this TSource source, Func<TSource, TResult> func)
    {
        if (func == null)
            throw new ArgumentNullException("func");

        if (source == null)
            return source;

        return func(source);
    }
}

몇 가지 확장 메서드를 작성하는 것과 동일한 문제가 발생했습니다.

public static TResult WhenNotNull<T, TResult>(
    this T subject, 
    Func<T, TResult> expression)
    where T : class
{
    if (subject == null) return default(TResult);
    return expression(subject);
}

public static TResult WhenNotNull<T, TResult>(
    this T subject, Func<T, TResult> expression,
    TResult defaultValue)
    where T : class
{
    if (subject == null) return defaultValue;
    return expression(subject);
}

public static void WhenNotNull<T>(this T subject, Action<T> expression)
    where T : class
{
    if (subject != null)
    {
        expression(subject);
    }
}

당신은 이것을 이렇게 사용합니다;

string str = null;
return str.WhenNotNull(x => x.Length);

또는

IEnumerable<object> list;
return list.FirstOrDefault().WhenNotNull(x => x.id, -1);

또는

object obj;
IOptionalStuff optional = obj as IOptionalStuff;
optional.WhenNotNull(x => x.Do());

nullable 형식에 대한 오버로드도 있습니다.

참조 URL : https://stackoverflow.com/questions/4244225/c-sharp-if-null-then-null-expression

반응형