簡體   English   中英

如何解壓縮表達式樹並檢查空值

[英]How to unpack an expression tree and check for null values

參考下面的兩個類,我經常寫這樣的LINQ語句。

using (var db = new DBContext())
{
    var result = db.Countries
        .Select(c => new
        {
            c.Name,
            c.Leader != null ? c.Leader.Title : String.Empty,
            c.Leader != null ? c.Leader.Firstname : String.Empty,
            c.Leader != null ? c.Leader.Lastname : String.Empty
        });
}

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Leader Leader { get; set; }
}

public class Leader
{
    public string Title { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

我的問題是我不得不經常重復我對子導航屬性的空檢查,我想知道是否有一種方法我可以使用某種表達式樹動態提取屬性值,同時檢查空值,如果他們沒有存在發回一個空字符串,類似於下面的方法..

public class Country
{
    // Properties //

    public string SafeGet(Expression<Func<Country, string>> fnc)
    {
        // Unpack fnc and check for null on each property?????
    }

}

用法:

using (var db = new DBContext())
{
    var result = db.Countries
        .Select(c => new
        {
            c.Name,
            c.SafeGet(l => l.Leader.Title),
            c.SafeGet(l => l.Leader.Firstname),
            c.SafeGet(l => l.Leader.Lastname)
        });
}

如果有人可以提供一個很好的基本示例,因為除了創建表達式樹之外,我沒有很多表達式樹的經驗。

謝謝。

更新 - >會像以下工作嗎?

public string GetSafe(Expression<Func<Country, string>> fnc)
{
    var result = fnc.Compile().Invoke(this);
    return result ?? string.Empty;
}

我認為沒有必要表達。 我只想去擴展方法

    public static class ModelExtensions
    {
         // special case for string, because default(string) != string.empty 
         public static string SafeGet<T>(this T obj, Func<T, string> selector)
         {
              try {
                  return selector(obj) ?? string.Empty;
              }
              catch(Exception){
                  return string.Empty;
              }
         }
   }

它適用於所有類,您可以進一步實現其他數據類型。 用法與您的相同。

我想你想要這樣的東西:

public static class ModelExtensions
{
    public static TResult SafeGet<TSource, TResult>(this TSource obj, System.Func<TSource, TResult> selector) where TResult : class
    {
        try
        {
            return selector(obj) ?? default(TResult);
        }
        catch(System.NullReferenceException e)
        {
            return default(TResult);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM