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

参考#

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。