myesn

myEsn2E9

hi
github

C#: nullのメンバーを呼び出しチェーンで見つける

背景#

var x = A?.B?.C?.D?.E;

もし A、B、C、D、または E のいずれかがnullである場合、xnullと評価されます。
では、どのメンバーの値がnullであるかを見つける方法はありますか?

方法一:条件チェック#

各メンバーに対して一連の条件チェックを行います:

String findNullMember(A a) {
    if (a is null) return "A";
    if (a.B is null) return "A.B";
    if (a.B.C is null) return "A.B.C";
    if (a.B.C.D is null) return "A.B.C.D";
    if (a.B.C.D.E is null) return "A.B.C.D.E";

    return "";
}

参照元:

方法二:Expression 表現#

Expressionを使用して文字列を生成することはできますが、式本体ではnull 条件演算子 (?.)を使用することはできません。

static string FindNullMember<T>(Expression<Func<T>> expression)
{
    Stack<MemberExpression> path = new();
    Expression? body = expression.Body;
    while (body is MemberExpression prop)
    {
        path.Push(prop);
        body = prop.Expression;
    }
    
    object? rootObject;
    switch (body)
    {
        case null:
        {
            // 静的プロパティにアクセス:
            rootObject = null;
            break;
        }
        case ConstantExpression c:
        {
            // インスタンスプロパティにアクセス:
            rootObject = c.Value;
            if (rootObject is null) return string.Empty;
            break;
        }
        default:
        {
            throw new ArgumentException($"サポートされていない式です: {expression}", nameof(expression));
        }
    }
    
    StringBuilder result = new();
    foreach (MemberExpression prop in path)
    {
        if (result.Length != 0) result.Append('.');
        result.Append(prop.Member.Name);
        
        switch (prop.Member)
        {
            case PropertyInfo pi:
            {
                rootObject = pi.GetValue(rootObject);
                break;
            }
            case FieldInfo fi:
            {
                rootObject = fi.GetValue(rootObject);
                break;
            }
            default:
            {
                result.Append("# サポートされていないメンバータイプです: ").Append(prop.Member.GetType().Name).Append('#');
                rootObject = null;
                break;
            }
        }
        
        if (rootObject is null) break;
    }
    
    return result.ToString();
}

使用方法:

string x = FindNullMember(() => A.B.C.D.E);

参照元:https://www.reddit.com/r/csharp/comments/1b9ojdu/comment/ktx9ehp/?utm_source=share&utm_medium=web2x&context=3

参考#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。