我的問題與以下兩個問題非常相似,但我有一個額外的要求,這些不滿足。如何從嵌套深度級別的表達式中設置值?
- How to set property value using Expressions?
- How set value a property selector Expression<Func<T,TResult>>
就像那些問題,我有一個Expression<Func<TEntity, TProperty>>
我想要的值設置爲指定的屬性。如果表達的主體只有一個深度,那麼這些解決方案就很有用,例如x => x.FirstName
,但如果該主體更深一些,它們根本不工作,如x => x.Parent.FirstName
。
有什麼方法可以採取這種深層次的表達方式併爲其設置價值嗎?我不需要一個強大的執行延期解決方案,但我確實需要一些我可以在對象上執行的東西,無論是1級還是多級,它都可以工作。我還需要支持您在數據庫中預期的大多數典型類型(long
,int?
,string
,Decimal
, DateTime?
等,儘管我不關心像地理類型這樣更復雜的事情)。
談話的緣故,讓我們說,我們正在與這些對象的工作,儘管假設我們需要處理N個級別深,不只是1或2:
public class Parent
{
public string FirstName { get; set; }
}
public class Child
{
public Child()
{
Mom = new Parent(); // so we don't have to worry about nulls
}
public string FavoriteToy { get; set; }
public Parent Mom { get; set; }
}
,讓我們說這是我們的單元測試:
[TestFixture]
public class Tests
{
[Test]
public void MyTest()
{
var kid = new Child();
Expression<Func<Child, string>> momNameSelector = (ch => ch.Mom.FirstName);
Expression<Func<Child, string>> toyNameSelector = (ch => ch.FavoriteToy);
kid.ExecuteMagicSetter(momNameSelector, "Jane");
kid.ExecuteMagicSetter(toyNameSelector, "Bopp-It!");
Assert.That(kid.Mom.FirstName, Is.EqualTo("Jane"));
Assert.That(kid.FavoriteToy, Is.EqualTo("Bopp-It!"));
}
}
,我們正在尋找(我沒有設置它需要是一個擴展方法,但它似乎很簡單),我們的擴展方法是這樣的:
public static TEntity ExecuteMagicSetter<TEntity, TProperty>(this TEntity obj, Expression<Func<TEntity, TProperty>> selector, TProperty value)
where TEntity : class, new() // I don't require this but I can allow this restriction if it helps
{
// magic
}
P.S.這個版本的代碼是在SO編輯器中編寫的 - 我對啞語法問題表示歉意,但是這應該是非常貼心的! #LockedDownWorkstationsSuck
只要表達式結束於屬性/字段,它就應該不會影響嵌套的成員表達式的深度。然後用這個表達式,你可以添加一個任務,你就完成了。 –
@JeffMercado從我嘗試過的那些問題的每個解決方案最終都有使用反射來調用setter方法的問題(在上面的示例中)「Parent」對象,但是通過「Child」對象的實例傳遞,所以在運行時出現類型不匹配失敗。我覺得缺失的魔法是遞歸或反覆獲取子屬性對象,然後將這些對象傳遞給setter方法。 – Jaxidian
那麼包括你在這個問題上的嘗試。您所描述的問題聽起來不像是與嵌套表達式相關的問題。如果你不是手動生成這些選擇器表達式並讓編譯器處理它,它首先必須是有效的表達式。 –