簡體   English   中英

在C#中定義和訪問所選屬性的最佳方法是什么?

[英]What's the best way to define & access selected properties in C#?

我最近的問題 ,我嘗試通過在域界面中包含一些愚蠢的邏輯來集中域模型。 但是,我發現了一些需要在驗證中包含或排除某些屬性的問題。

基本上,我可以像下面的代碼一樣使用表達式樹。 不過,我不喜歡它,因為每次創建lambda表達式時我都需要定義局部變量(“u”)。 你有比我短的源代碼嗎? 此外,我需要一些方法來快速訪問選定的屬性。

public void IncludeProperties<T>(params Expression<Func<IUser,object>>[] selectedProperties)
{
    // some logic to store parameter   
}

IncludeProperties<IUser>
(
    u => u.ID,
    u => u.LogOnName,
    u => u.HashedPassword
);

謝謝,

Lambdas適用於許多場景 - 但如果您不想要它們,可能根本就不使用它們? 我不想這么說,但是對簡單的字符串進行了嘗試和測試,特別是對於數據綁定等場景。 如果你想要快速訪問,你可以查看HyperDescriptor,或者有方法編譯屬性訪問器的委托,或者你可以從字符串構建一個Expression並編譯它(如果你想要一個已知的簽名,包括一個轉換為object ,而不是調用(慢得多) DynamicInvoke )。

當然,在大多數情況下,即使粗反射也足夠快,而且不是瓶頸。

我建議從最簡單的代碼開始,檢查它實際上是太慢了,然后再擔心它的速度很快。 如果不是太慢,請不要更改它。 除非上述任何選項都有效。


另一個想法; 如果您正在使用Expression ,您可以執行以下操作:

public void IncludeProperties<T>(
    Expression<Func<T,object>> selectedProperties)
{
    // some logic to store parameter   
}

IncludeProperties<IUser>( u => new { u.ID, u.LogOnName, u.HashedPassword });

然后把表達分開? 有點整潔,至少......這里有一些展示解構的示例代碼:

public static void IncludeProperties<T>(
    Expression<Func<T, object>> selectedProperties)
{
    NewExpression ne = selectedProperties.Body as NewExpression;
    if (ne == null) throw new InvalidOperationException(
          "Object constructor expected");

    foreach (Expression arg in ne.Arguments)
    {
        MemberExpression me = arg as MemberExpression;
        if (me == null || me.Expression != selectedProperties.Parameters[0])
            throw new InvalidOperationException(
                "Object constructor argument should be a direct member");
        Console.WriteLine("Accessing: " + me.Member.Name);
    }
}
static void Main()
{
    IncludeProperties<IUser>(u => new { u.ID, u.LogOnName, u.HashedPassword });
}

一旦你知道了MemberInfo (上面的me.Member ),為個人訪問建立你自己的lambdas應該是微不足道的。 例如(包括轉換為object以獲取單個簽名):

var param = Expression.Parameter(typeof(T), "x");
var memberAccess = Expression.MakeMemberAccess(param, me.Member);
var body = Expression.Convert(memberAccess, typeof(object));
var lambda = Expression.Lambda<Func<T, object>>(body, param);
var func = lambda.Compile();

這是我能提出的最短的表達方式:

public static void IncludeProperties(Expression<Action<IUser>> selectedProperties)
{
    // some logic to store parameter   
}

public static void S(params object[] props)
{
    // dummy method to get to the params syntax
}

[Test]
public void ParamsTest()
{
    IncludeProperties(u => S(
        u.Id,
        u.Name
        ));

}

暫無
暫無

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

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