根据用法推断参数类型

时间:2011-12-08 16:20:58

标签: c# reflection

我有线问题,我知道推理需要使用开放的通用。

是一种调用AssertDictionary(o2,o1)的方法;通过反思。 我想要的是,使用o1的类型说t1和o2说t2作为AssertDictionary(o1,o2);

这有意义吗?

 public static void Main(String[] args)
    {
        Dictionary<int, Person> actual = new Dictionary<int, Person>();
        actual.Add(10, new Person{Address="Abc", Name = "Dipak"});

        Dictionary<int, Person> expected = new Dictionary<int, Person>();
        expected.Add(10, new Person { Address = "Abc", Name = "Dipak" });

        object o1 = actual;
        object o2 = expected;
        CallAssert(o1, o2);
    }

     private static CallAssert(object exp, object act)
     {
            AssertDictionary(exp, act);// I'm doing it at runtime by reflection and actual & expected are of type System.Object
     }


 private static void AssertDictionary<TKey, TVal>(Dictionary<TKey, TVal> expected, Dictionary<TKey, TVal> actual)
    {
        if (expected != null && actual != null)
        {
            foreach (KeyValuePair<TKey, TVal> valuePair in expected)
            .....
            .....
        }
     }

我可以在运行时创建动态方法,并使用Generic类型从那里调用AssertDictionary吗?

2 个答案:

答案 0 :(得分:2)

如果您确定必须使用反射,则可以这样做(假设Program是包含AssertDictionary()的类型):

// get the method
var openMethod = typeof(Program).GetMethod(
    "AssertDictionary", BindingFlags.NonPublic | BindingFlags.Static);

// get type arguments of the dictionary
var dictTypeArgs = o1.GetType().GetGenericArguments();

// set the type parameters of the method
var closedMethod = openMethod.MakeGenericMethod(dictTypeArgs);

// invoke the method
closedMethod.Invoke(null, new [] { o1, o2 });

另一种选择是使用dynamic并在运行时自动推断类型参数:

AssertDictionary((dynamic)o1, (dynamic)o2);

我认为这里不需要创建任何动态方法。

答案 1 :(得分:0)

如果你正在计划使用反射,你假设你已经知道你正在试图迭代memebrs的类型。

试试这个:

        Dictionary<int, Person> actual = new Dictionary<int, Person>();
        actual.Add(10, new Person { Address = "Abc", Name = "Dipak" });

        Dictionary<int, Person> expected = new Dictionary<int, Person>();
        expected.Add(10, new Person { Address = "Abc", Name = "Dipak" });

        object o1 = actual;
        object o2 = expected;

        AssertDictionary((Dictionary<int, Person>)o2, (Dictionary<int, Person>)o1);

或者您可以通过使用dynamic关键字告诉编译器您正在做什么。

AssertDictionary((dynamic)o1, (dynamic)o2);

并且为了避免必须将每种类型转换为动态类型,那么您应该修改该方法而不是我不会使用此技术重新构建

    private static void AssertDictionary(dynamic expected, dynamic actual)
    {
        // you will be able to call methods as:
        actual.Add(1, new Person()); // intelisence will not help you you have to be carefull with the dynamic type
        // I dont recoment using it if there is a work around
    }

svik代码看起来好多了。如果我在哪里,我会使用他的代码......