向下转换ComponentRegistration到非泛型类型

时间:2015-09-22 07:05:16

标签: c# generics reflection casting castle-windsor

我正在使用Castle.Windsor库,我想要的是获得"实施"属性,来自IRegistration []的所有项目。

我有以下接口和类:

action="<?php echo $_SERVER['PHP_SELF']; ?>"

包含此组件的静态类:

public interface IA
  {
    int a { get; set; }
  }

  public class A : IA
  {
    public int a { get; set; }
  }

  public interface IB
  {
    int b { get; set; }
  }

  public class B : IB
  {
    public int b { get; set; }
  }

当然,变量a在每次迭代后都为null。 它只适用于我转换为Generic ComponentRegistration

  public static class Bootekstraperek
  {
    private static readonly IRegistration[] _commonRegistrations =
    {
      Component.For<IA>().ImplementedBy<A>(),
      Component.For<IB>().ImplementedBy<B>()
    };

    public static void Test()
    {
      List<IRegistration> list = _commonRegistrations.ToList();

      foreach (var registration in list)
      {
        ComponentRegistration a = registration as ComponentRegistration;
        Console.WriteLine(a.Implementation.FullName);
      }
    }
  }

但是,如果我在这个数组中有太多不同的组件,那对我没有帮助。所以Switch语句不是一个选项。 我尝试过使用反射,但我仍然无法正确施放。

如何使用或不使用反射来实现我想要的效果?

thxia。

2 个答案:

答案 0 :(得分:2)

这并不容易,因为IRegistration API从未打算以这种方式使用。

所以我的答案分为两部分。

  1. 你如何做到这一点。使用dynamic
  2. 您只需要更改一小部分代码:

    foreach (dynamic registration in list)
    {
      Console.WriteLine(registration.Implementation.FullName);
    }
    
    1. 您在此尝试实现的基本目标是什么?如果您的目标是保持对注册内容,如何以及如何关注潜在问题的可见性,请查看Windsor的诊断。

答案 1 :(得分:1)

少量反射解决了这个问题(这个问题很少,但看起来很冗长,因为反射):

foreach (var registration in list)
{
  Console.WriteLine(
         ((Type)registration.GetType().GetProperty(
                "Implementation"
         ).GetGetMethod().Invoke(
                registration,new object[] { })
         ).FullName);
}

由于您在运行之前不知道被用作通用类型参数的类型,因此我认为没有任何反射可以做到这一点。

以上假设的所有注册都是ComponentRegistration<T>某种对象。如果这是一个不安全的假设,可能有IRegistration的其他一些实现没有实现Implementation属性,或者可能无法公开访问 - 因此请插入适当的临时错误检查如果是这样的话。