簡體   English   中英

C#,如何從動態對象的字符串參數傳遞屬性名稱

[英]C#, How to pass property name from string parameter for Dynamic object

我的API響應將返回JSON對象的列表,我需要驗證列表的順序,因此我編寫了如下函數。 但是我對LINQ按句排序有一個問題,它僅在指定實際字段時才有效,但是我需要將此字段名稱作為參數傳遞。 所以像var expectedList = jObjList.OrderBy(x => x.parameterFieldName.ToString()); 請給我一些建議,非常感謝。

public void VerifyOrderBy(string jsonString, string parameterFieldName)
{
    List<dynamic> jObjList = JsonConvert.DeserializeObject<List<dynamic>>(jsonString);
    var expectedList = jObjList.OrderBy(x => x.LastName.ToString());
    Assert.IsTrue(expectedList.SequenceEqual(jObjList));
}

JSON字符串如下所示

[
    {
        "FirstName": "w3pCj",
        "LastName": "mSJOV",
        "IsDeleted": false
    },
    {
        "FirstName": "rMnH7",
        "LastName": "rMnH7",
        "IsDeleted": false
    },
    {
        "FirstName": "Jia",
        "LastName": "Yu",
        "IsDeleted": false
    }
] 

您可以像這樣使用nameof()運算符關鍵字:

jObjList.OrderBy(x => nameof(x.LastName));

更新#1

假設我們有一個Person類:

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public bool IsDeleted { get; set; }
}

假設我們有一個人員列表:

var people =
    JsonConvert
        .DeserializeObject<List<Person>>(
            File.ReadAllText("data.json", Encoding.UTF8)
        );

我們可以有一個包含將要按以下順序排序的屬性名稱的參數:

string parameterName = nameof(Person.LastName); // or simply "LastName"

我們得到對該屬性的引用:

PropertyInfo orderByProperty =
    typeof(Person)
        .GetProperties()
        .SingleOrDefault(property => property.Name == parameterName);

現在我們可以按選定的屬性排序:

var result = people.OrderBy(person => orderByProperty.GetValue(person)).ToList();

請注意:

  • 當然,您應該檢查orderByProperty是否不為null :)
  • 這僅適用於內存中對象(LINQ-to-Objects),而不適用於數據庫集(LINQ-to-SQL,EF)

不要忘記添加所需的using語句才能獲得PropertyInfo

using System.Reflection;

更新#2

如果您具有如此簡單的json結構,並且想使用dynamic對象進行排序,則可以這樣實現:

var people =
    JsonConvert
        .DeserializeObject<List<dynamic>>(
            File.ReadAllText("data.json", Encoding.UTF8)
        );

string parameterName = "LastName";

var result =
    people
        .OrderBy(person =>
        {
            var personObject = person as JObject;
            var propertyValueObject = personObject.GetValue(parameterName) as JValue;

            return propertyValueObject.Value;
        })
        .ToList();

雖然可以,但是我更喜歡UPDATE#1解決方案。 :)

這是使用自定義比較器的實現。 這使您可以傳遞任何屬性名稱:

public class JObjComp<T> : IComparer<T>
{
    private string _field;

    public JObjComp(string field)
    {
        _field = field;
    }

    int IComparer<T>.Compare(T a, T b)
    {
        //this is bit flimsy but as we know that passed object is 
        //a dynamic, should work
        dynamic aa=(dynamic)a;
        dynamic bb=(dynamic)b;
        return string.Compare(aa[_field].ToString(), bb[_field].ToString());
    }
}

現在使用我們的自定義比較器:

List<dynamic> jObjList = JsonConvert.DeserializeObject<List<dynamic>>(jstr);
jObjList.Sort(new JObjComp<dynamic>(field));

該列表是就地排序的,因此您可以使用jObjList本身進行斷言。

暫無
暫無

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

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