我的地方,我們在表中添加下列值場動態地在現有的類C#運行時添加的屬性
- 產品名稱
- 產品編號
- 產品代碼
我有一個現有的類產品與一些現有的屬性
我找這將在現有的類產品在運行時(動態),當用戶在表中增加值場
我的地方,我們在表中添加下列值場動態地在現有的類C#運行時添加的屬性
我有一個現有的類產品與一些現有的屬性
我找這將在現有的類產品在運行時(動態),當用戶在表中增加值場
定義添加屬性的方法:
public class Product
{
public string ProductID { get; set; }
//product in a product search listing
public string StoreName { get; set; }
public string SearchToken { get; set; }
public Dictionary<string, object> Fields { get; set; }
}
用法:
var Prod = new Product();
Prod.Fields.Add("MyCustomFieldString", "my value here");
Prod.Fields.Add("MCustomFieldInt", 123);
MessageBox.Show(Prod.Fields[MyCustomFieldString].ToString());
MessageBox.Show(Prod.Fields[MCustomFieldInt].ToString());
好的感謝CathalMF,但我期待這個新添加的屬性將作爲永久屬性存在於產品類 – amethianil
@amethianil Permanant屬性將要求您更改代碼,這意味着在運行時編譯和替換dll。這對於簡單添加新的搜索欄來說似乎很瘋狂。 – CathalMF
我不知道在運行時定義屬性的方法,但是另一種實現您需要的方法是在C#中使用名爲ExpandoObject
的動態對象。
你首先需要聲明你的動態對象,它在內部使用一種字典,然後你可以添加你的屬性。
using System.Dynamic;
dynamic newobj = new ExpandoObject();
//I can add properties during compile time such as this
newobj.Test = "Yes";
newobj.JValue = 123;
//Or during runtime such as this (populated from two text boxes)
AddProperty(newobj, tbName.Text, tbValue.Text);
public void AddProperty(ExpandoObject expando, string name, object value)
{
var exDict = expando as IDictionary<string, object>;
if (exDict.ContainsKey(propertyName))
exDict[propertyName] = propertyValue;
else
exDict.Add(propertyName, propertyValue);
}
我在這裏一個解決方案中使用了一次:Flattern child/parent data with unknown number of columns
但這些來源也許可以更好地解釋它; https://www.oreilly.com/learning/building-c-objects-dynamically
https://weblog.west-wind.com/posts/2012/feb/08/creating-a-dynamic-extensible-c-expando-object
https://docs.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/types/using-type-dynamic
但是,我不知道這會真的爲您提供了使用簡單的Dictionary<string, object>
好的jason.kaisersmith謝謝你的回覆。我看起來不像ExpandoObject,因爲我們只能在運行時使用這個ExpandoObject對象。但我希望新添加的屬性將作爲屬性在我的課程中永久存在。將來我們將使用它作爲類屬性。如果一個用戶在表中添加了一個新字段,那麼它會自動添加爲我的Product類中的屬性 – amethianil
任何真正的優勢,你需要澄清(也許你自己)你需要什麼,或者我會說,你想要什麼。
編譯完代碼後,將根據您的類型\方法\字段生成元數據。有很多表格(45個更具體)來描述你的數據。
所以,如果你想添加新的屬性到某種類型,你需要添加新的行到元數據表。要添加新行,您需要編譯代碼,您需要。
那麼什麼是Refelection.Emit
?是在您的應用中動態創建新數據的一種方式。有了這個,你創建一個動態組件,動態類型,動態方法,添加一些IL,然後你去。但是,所有這一切都是在內存。而不是你想要的。
所以,或者動態數據使用Emit
\ ExpandoObject
,或靜態數據通過向代碼添加屬性並編譯它。
你也有一種運行時編譯方式之間的方法,它通過使用它來調用Mono.Cecil
,你可以通過代碼添加新的屬性來鍵入,然後編譯它並加載新的DLL到你的AppDomain
或者只是關閉應用程序並重新享用午餐。它可以自動,只需通過代碼。沒有什麼魔力,它會將數據添加到程序集中的元數據表中,但它可以縮短手動執行此操作的方式。
但還有一個選項,我相信你知道它。我正在使用Visual Studio
,你可能聽說過Edit and Continue
(EnC)。此功能實際上是將新代碼寫入您的正在運行的程序集,並將新數據(僅限新增)添加到元數據中。
所以,我不能告訴你,你應該做的,因爲我不知道到底是什麼你的情況下,有是,人們希望當他們不再需要他們極端的解決方案的情況下,但如果你真的必須選擇要將新的數據添加到已運行的程序集中,EnC
可以成爲解決方案。要使用EnC
,請查看Roslyn
代碼中的功能(您可能想要檢查其測試以瞭解如何使用)。之後,看看@Josh Varty例子here。
所有我寫的,我真的(X3)不認爲你需要做出一些瘋狂的你所需要的。我相信有一個更好,簡單的方法來做到這一點。
好的,謝謝Dudi Keleti - 我已經使用ExpandoObjexct – amethianil
您不能在運行時修改類定義,除非您遇到一些非常複雜的東西並編寫一些部分類,在運行時編譯成dll並將它們加載到內存中。聽起來就像你只需要一個Dictionary,所以你可以存儲值並給它們一個名字。 –
CathalMF
實際上忽略了我之前關於在運行時編譯部分類的聲明,這甚至不可能。 – CathalMF
好的,謝謝CathalMF – amethianil