[英]Is it possible to declare an anonymous type in C# with a variable/dynamic set of fields?
在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的創作者非常清楚這個問題。 INSERT
和UPDATE
助手確實需要這種功能。
Query
, Execute
和QueryMultiple
方法接受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 。
您不能使用匿名類型。 匿名類型由編譯器生成,而不是在運行時生成。 你當然可以使用dynamic
:
dynamic dynamicObj = new ExpandoObject();
var objAsDict = (IDictionary<String, Object>)dynamicObj;
foreach(var item in paramList)
{
objAsDict.Add(item.Item1, item.Item2);
}
然后,您可以將dynamicObj用作常規對象:
Console.WriteLine(dynamicObj.key1); // would output "value1"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.