myesn

myEsn2E9

hi
github

C#: 找到调用链中值为 null 的成员

背景#

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

如果 A、B、C、D 或 E 中的任何一个为 null,则 x 将被计算为 null
那么,有没有办法找到哪个成员的值为 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 表达式#

可以使用表达式来生成字符串,但无法在表达式主体中使用 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:
        {
            // Accessing a static property:
            rootObject = null;
            break;
        }
        case ConstantExpression c:
        {
            // Accessing an instance property:
            rootObject = c.Value;
            if (rootObject is null) return string.Empty;
            break;
        }
        default:
        {
            throw new ArgumentException($"Unsupported expression: {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("# Unsupported member type: ").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

参考#

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.