亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在編譯表達式之前測試空子

在編譯表達式之前測試空子

C#
鳳凰求蠱 2022-06-19 10:15:04
我正在嘗試通過 檢索一個值Expression,但我有一個場景,模型上的子屬性為 null 并且我得到一個NullReferenceException.該場景發生在我以以下方式使用模型的情況下,x視圖中的模型在哪里并且它不為空,但Contact屬性為空:x => x.Contact.Email然后我使用以下方法檢索該值:public static FieldInfo Get<TModel, TProperty>(HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression){    object value = null;    if (html.ViewData.Model != null)    {        value = expression.Compile()(html.ViewData.Model);    }    // other code}如何調整此代碼以測試子屬性上的 null 還是不可能的?
查看完整描述

2 回答

?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

為了在我的IQueryable左外連接實現中處理這個問題,我使用了一個ExpressionVisitor替換null.member為null. 您可以在ExpressionEF/LINQ to SQL 支持的 .


public static class ExpressionExt {

    public static TE AddTestForNull<TE>(this TE orig) where TE : Expression => (TE)(new NullTestVisitor().Visit(orig));

}



/// <summary>

/// ExpressionVisitor to replace a obj.member Expression with a null test ((obj == null) ? null : obj.member)

/// </summary>

public class NullTestVisitor : System.Linq.Expressions.ExpressionVisitor {

    public override Expression Visit(Expression node) {

        if (node is MemberExpression nme)

            return Expression.Condition(Expression.MakeBinary(ExpressionType.Equal, nme.Expression.AddTestForNull(), Expression.Constant(null, nme.Expression.Type)),

                                        Expression.Constant(null, nme.Type),

                                        nme);

        else

            return base.Visit(node);

    }

}

然后,當您需要處理此類問題時Expression,只需繼續AddTestForNull:


value = expression.AddTestForNull().Compile()(html.ViewData.Model);

這將在每個級別添加測試 - 如果您有x => x.member.testMember,它將被替換為((x == null ? null : x.member) == null ? null : x.member.testMember).


查看完整回答
反對 回復 2022-06-19
?
Helenr

TA貢獻1780條經驗 獲得超4個贊

您是否可以調整 Get(..) 方法以使用 Func 而不是表達式?


表達式不允許 Null Coalescing 或 Null Propagation 運算符。但是函數可以。


//Yours

public static FieldInfo Get<TModel, TProperty>(HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression) { ... }


//Potential solution for you

public static FieldInfo Get<TModel, TProperty>(HtmlHelper<TModel> person, Func<TModel, TProperty> func) { ... }

表達式不允許 Null Coalescing 或 Null Propagation 運算符。但是函數可以。


請原諒類型的差異。我正在使用我當時最容易獲得的東西來為你創建一個具體的例子。


請注意,調用的是 Invoke() 方法而不是 Compile()


public static object Get<Person, TProperty>(Person person, Func<Person, TProperty> func)

{

    object result = null;


    if (person != null)

    {

        result = func.Invoke(person);

    }


    return result;

}

示例使用

var personNoContact = new Person { Contact = null };

var result = Get(personNoContact, x => x.Contact?.Email.EmailAddress ?? "");

以下類用于測試

public class Person

{

    public Contact Contact { get; set; }

}


public class Contact

{

    public Email Email { get; set; }

}


public class Email { public string EmailAddress { get; set; } }


查看完整回答
反對 回復 2022-06-19
  • 2 回答
  • 0 關注
  • 132 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號