【问题标题】:Using Activator.CreateInstance(Type t), how to cast 'object' to 'T' to add to List<T>使用 Activator.CreateInstance(Type t),如何将 'object' 转换为 'T' 以添加到 List<T>
【发布时间】:2021-02-25 16:25:25
【问题描述】:

在自定义 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 的这种用法传递了正确的对象,但它仍然是类型 object

这样做的结果相同:

   var assemName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

   var thng = Activator.CreateInstance(assemName, ListObjectType.FullName);
   var thng2 = thng.Unwrap();

【问题讨论】:

  • 为什么包含类也不是泛型的,那么你可以说var thng = new T();?你不能做as MyTypeVariable,它是无效的
  • ItemsSourceClass.Things的类型是什么?
  • @Charlieface 这段代码在一个控件中,可以交给一个 ICollection,其中 T 几乎可以是任何东西。
  • @canton7 public class SimpleClass { public string Name {get;设置;}公共字符串颜色{get;集;}公共整数计数{get;设置;}
  • @Cat 你的SimpleClass 上没有Add 方法...ItemsSourceClass.Things 的类型是什么?

标签: c# observablecollection activator


【解决方案1】:

您还需要使用反射来调用Add

ItemsSourceClass.Things
    .GetType()
    .GetMethod(nameof(ItemsSourceClass.Things.Add))
    .Invoke(ItemsSourceClass.Things, new object[] { thng });

【讨论】:

    猜你喜欢
    • 2019-02-03
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    相关资源
    最近更新 更多