如何解决使用 Activator.CreateInstance(Type t),如何将 'object' 转换为 'T' 以添加到 List<T>
在自定义 WPF 控件中工作,我们需要允许用户将新对象添加到列表中(类似于 IsEditable = true 时的 ComboBox)。
ItemsSource 是一个 ObservableCollection
当用户输入一个字符串时,控件需要创建一个新的T对象并将其添加到列表中。
我们有一个方法可以从ItemsSource对象中判断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 的一个新实例 - 直到我们尝试将新对象添加到 ItemsSource 集合。
由于 Activator.CreateInstance(Type t) 返回 object,看来我们需要将 thng 转换为 T 以添加到 ObservableCollection
我们尝试了各种方法让 ItemsSource 集合相信 thng 是正确的类型,但没有找到一种有效的方法。
我们错过了什么?
更新
我们添加了一个依赖变量:
public static readonly DependencyProperty ListObjectTypeProperty =
DependencyProperty.Register("ListObjectType",typeof(Type),typeof(AutoCompleteComboBox));
在 xaml 中:
ListObjectType="{x:Type local:SimpleClass}"
ListObjectTypeProperty 的这种用法提供了正确的对象,但它仍然是 Type 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 });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。