是否可以使用變量/動態字段集在C#中聲明匿名類型?

anonymous-types c# dapper dynamic

在C#中,我想弄清楚是否可以聲明一個匿名類型,其中字段在運行時才知道。

例如,如果我有一個鍵/值對列表,我可以根據該列表的內容聲明一個匿名類型嗎?我正在使用的具體情況是將參數傳遞給Dapper,我不知道我將提供多少參數。

List<Tuple<string, string>> paramList = new List<Tuple<string, string>>() {
    new Tuple<string, string>("key1", "value1"),
    new Tuple<string, string>("key2", "value2")
    ...
};

我想將此List(或等效的Map)轉換為匿名類型,我可以將其作為查詢參數傳遞給Dapper。理想情況下,如果將以上列表定義為匿名類型,則上面的列表最終會顯示如下:

new { key1=value1, key2=value2, ... }

我在StackOverflow上看到了幾個問題,詢問在聲明它們之後擴展匿名類型(“extendo objects”),或者在創建對像後聲明任意字段,但我不需要這樣做......我只是需要一次性地動態聲明類型。我懷疑它是否需要一些花哨的反思,如果可能的話。

我的理解是編譯器在編譯時為引擎定義了一個匿名類的類型,所以如果該類的字段在運行時才可用,我可能會運氣不好。實際上,我的用例實際上與使用“extendo對象”來定義任意字段無關。

或者,如果有人知道將查詢參數傳遞給Dapper的更好方法(而不是聲明一個匿名類),我也很想知道這一點。

謝謝!

UPDATE

抱歉延遲回到這個!這些答案都很棒,我希望我能給大家一點。我最終使用了jbtule的解決方案(由Sam Saffron編輯),將IDynamicParameters傳遞給Dapper,所以我覺得我必須給他答案。其他答案也很好,並回答了我提出的具體問題。我非常感謝大家的時間!

一般承認的答案

Dapper的創作者非常清楚這個問題。 INSERTUPDATE助手確實需要這種功能。

QueryExecuteQueryMultiple方法接受dynamic參數。這可以是匿名類型,具體類型或實現IDynamicParameters的對象。

public interface IDynamicParameters
{
    void AddParameters(IDbCommand command, Identity identity);
}

這個界面非常方便,在運行任何SQL之前調用AddParameters 。這不僅可以豐富地控制發送給SQL的參數。它允許您連接DB特定的DbParameters,因為您可以訪問該命令(您可以將其強制轉換為特定於db的命令)。這允許支持表值參數等。

Dapper包含此接口的實現,可用於您的目的,稱為DynamicParameters 。這允許您連接匿名參數包並添加特定值。

您可以使用AddDynamicParams方法追加匿名類型。

var p = new DynamicParameters();
p.AddDynamicParams(new{a = "1"});
p.AddDynamicParams(new{b = "2", c = "3"});
p.Add("d", "4")
var r = cnn.Query("select @a a, @b b, @c c, @d d", p);
// r.a == 1, r.b == 2, r.c == 3, r.d == 4

熱門答案

在C#中,我想弄清楚是否可以聲明一個匿名類型,其中字段在運行時才知道。

匿名類型由編譯器生成。您想知道編譯器是否會生成編譯器生成的類型, 其中包含編譯器不知道的字段類型 。顯然它不能這樣做;正如你猜測的那樣,你運氣不好。

我已經在StackOverflow上看到幾個問題,詢問在聲明它們之後擴展匿名類型(“extendo objects”)

我們通常稱這些“expando”對象。

如果你想要做的是基於鍵值對的字典創建一個expando對象,那麼使用ExpandoObject類來做到這一點。有關詳細信息,請參閱此MSDN文章:

http://msdn.microsoft.com/en-us/magazine/ff796227.aspx

如果你想要做的是在運行時生成一個真正的.NET類,你也可以這樣做。正如您所正確注意的那樣,您需要一些花哨的反思才能這樣做。你想要做的是做一個可收集的程序集(所謂的,因為與普通程序集不同,你在運行時生成它,垃圾收集器將在你完成它時清理它。)

有關如何使用TypeBuilder創建可收集程序集並向其中發出類型的詳細信息,請參閱http://msdn.microsoft.com/en-us/library/dd554932.aspx



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因