[英]Using Activator.CreateInstance(Type t), how to cast 'object' to 'T' to add to List<T>
在自定義 WPF 控件中工作,我們需要允許用戶將新的 object 添加到列表中(類似於 IsEditable = true 時的 ComboBox)。
ItemsSource 是一個 ObservableCollection<T>。
當用戶輸入字符串時,控件需要新建一個 T object 並添加到列表中。
我們有一個方法可以從ItemsSource object中判斷T是什么類型,然后使用Activator.CreateInstance()創建一個T:
private Type _typ;
public void AddSomething(object o)
{
var iCollection = o as ICollection;
if (iCollection != null)
{
dynamic oc = iCollection;
_typ = GetGenericType(oc);
Debug.WriteLine($" ICollection<T> T type: {_typ}");
var thng = Activator.CreateInstance(_typ);
Debug.WriteLine($" thng Type: {thng.GetType()}");
ItemsSourceClass.Things.Add(thng as _typ);
// Compile time error:
CS0246 The type or namespace name '_typ' could not be found (are you missing a using directive or an assembly reference?)
/* snip */
這一切都按預期工作 - thng 是 T 的一個新實例 - 直到我們嘗試將新的 object 添加到 ItemsSource 集合中。
由於 Activator.CreateInstance(Type t) 返回object ,看來我們需要將 thng 轉換為T以添加到 ObservableCollection<T>。
我們嘗試了各種方法來讓 ItemsSource 集合相信 thng 是正確的類型,但還沒有找到一種有效的方法。
我們缺少什么?
更新
我們添加了一個依賴變量:
public static readonly DependencyProperty ListObjectTypeProperty =
DependencyProperty.Register("ListObjectType", typeof(Type), typeof(AutoCompleteComboBox));
在 xaml 中:
ListObjectType="{x:Type local:SimpleClass}"
ListObjectTypeProperty 的這種用法提供了正確的 object,但它仍然是類型object :
這樣做的結果相同:
var assemName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
var thng = Activator.CreateInstance(assemName, ListObjectType.FullName);
var thng2 = thng.Unwrap();
您還需要使用反射來調用Add
:
ItemsSourceClass.Things
.GetType()
.GetMethod(nameof(ItemsSourceClass.Things.Add))
.Invoke(ItemsSourceClass.Things, new object[] { thng });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.