【问题标题】:Given a collection object, would like to assign to a local variable of specific type给定一个集合对象,想要分配给特定类型的局部变量
【发布时间】:2011-12-09 05:50:19
【问题描述】:

我想使用反射来恢复类型信息。我有

public Foo(object coll, string tValue)
{
   var x = col1 as IList;
   if (x != null)
      x.Action();

   var y = col1 as IDictionary;
   if (y != null)
      y.Action();
}

但想拥有

public Foo(object coll, string tValue)
{
   var x = col1 as IList<TValue>;
   if (x != null)
      x.Action();

   var y = col1 as IDictionary<int, TValue>;
   if (y != null)
      y.Action();
}

如果只给定包含的类名,是否可以使用泛型接口而不是老式的非泛型集合接口?

一旦建立了局部变量类型,我想避免在循环集合时支付反射和动态调用惩罚。

另一个例子,也许更清楚:

     var list = new Dictionary<int, MyObject>();
     list.Add(100, new MyObject());

     object listObject = list;

     var x = listObject as IDictionary<int, dynamic>;
     if (x != null)
     {
        foreach (var entry in x)
        {
           Console.WriteLine(entry.Key);
           Console.WriteLine(entry.Value);
        }
     }

x 为空...

【问题讨论】:

  • 在你调用这个函数的地方知道类型吗?是否可以使用泛型(即,使 Foo 函数泛型)。
  • 您的集合中的项目数量是否需要优化反射对性能的影响?做你想做的事情的反射实际上非常快,就像在中端 CPU 上每次调用只需几纳秒。谷歌基准测试。

标签: c#-4.0 reflection types collections


【解决方案1】:

我不确定您是否打算为集合中的每个项目调用通用集合上的方法,或者您是否只想要通用集合中的值。

对于您的第三个代码块,您可以继续使用非泛型接口并使用枚举器。

        var x = listObject as IDictionary;
        if (x != null)
        {
            var en = x.GetEnumerator();
            while(en.MoveNext())
            {
                Console.WriteLine(en.Key);
                Console.WriteLine(en.Value);
            }
        }

如果您打算在不知道泛型 IList 或 IDictionary 的确切泛型类型的情况下调用方法,则必须使用 MethodInfo.Invoke。将 MethodInfo 缓存在循环之外以提高性能。 CreateDelegate 会更快,但您需要知道确切的泛型类型。您可以使用表达式树来解决这个问题,但要维护的代码量可能不值得性能提升。查看 Jon Skeets 文章中的 MagicMethod Making reflection fly and exploring delegates

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    相关资源
    最近更新 更多