使用动态类型调用generics扩展方法

我正在尝试执行返回类型为T的对象的扩展方法,但我正在尝试根据Header / Detail动态generics类型来设置类型T dynamic。

这可能有点冗长……

using System; using System.Collections.Generic; namespace Blah { public interface IHeader { string Name { get; set; } IDetail Detail { get; set; } } public interface IDetail { //Nothing the 'Real' implementation of this //interface will have it's own properties. } public class GenericHeader : IHeader { public string Name { get; set; } public IDetail Detail { get; set; } } public class RealHeader : GenericHeader { public new RealDetail Detail { get { return (RealDetail) base.Detail; } set { base.Detail = value; } } } public class RealDetail : IDetail { public string ThisImportantOnlyToRealDetail { get; set; } } public static class ExtensionHelpers { public static T ToObject(this IDictionary reader) where T : new() { //This maps the dictionary to Key Value Pairs of the Object's properties //it then will return a object filled with the values return new T(); } } public class MyRepo where THeader : class, IHeader, new() { public THeader GetById(int ID) { THeader returnHeader = new THeader(); //Process to fill Header var dictDetail = new Dictionary(); //Process to fill Detail Dictionary //Use extension method to create an Object //based on Key Value Pairs from Dictionary // !!!!!!!!!!!!!!!! This Is The Problem !!!!!!!!!!!!!!!! // Can't use typeof for returnHeader.Detail, reflection? returnHeader.Detail = dictDetail.ToObject(); return returnHeader; } } public class Worker { public void DoWork() { var myRealRepo = new MyRepo(); var myRealHeader = myRealRepo.GetById(123); Console.WriteLine(myRealHeader.Detail.ThisImportantOnlyToRealDetail); } } } 

这必须使用reflection来完成。

 typeof(ExtensionHelpers) .GetMethod("ToObject", BindingFlags.Static | BindingFlags.Public) .MakeGenericMethod(returnHeader.Detail.GetType()) .Invoke(null, new object[] { dictDetail }); 

请注意,由于扩展方法是一种语言function,因此在使用reflection时必须像使用常规静态方法一样调用该方法。

如果类型始终是动态的,则可能更容易将ToObject更改为将Type作为参数的常规非generics方法。


实际上你的设计有点问题,因为你似乎需要知道Detail属性背后的对象的实际类型,但这需要该属性已经有一个值,但你的代码正在设置该属性。

我建议你考虑其他方法来解决这个问题。