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:
        {
            // 存取靜態屬性:
            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

參考#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。