c# - 使用动态类型调用泛型扩展方法

标签 c# generics types extension-methods dynamic

<分区>

我正在尝试执行一个返回类型为 T 的对象的扩展方法,但我正在尝试使类型 T 动态基于标题/详细信息动态泛型。

这可能有点冗长......

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<T>(this IDictionary<string, string> 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<THeader> where THeader : class, IHeader, new()
    {
        public THeader GetById(int ID)
        {
            THeader returnHeader = new THeader();
            //Process to fill Header

            var dictDetail = new Dictionary<string, string>();
            //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<typeof(returnHeader.Detail)>();

            return returnHeader;
        }
    }

    public class Worker
    {
        public void DoWork()
        {
            var myRealRepo = new MyRepo<RealHeader>();
            var myRealHeader = myRealRepo.GetById(123);

            Console.WriteLine(myRealHeader.Detail.ThisImportantOnlyToRealDetail);
        }
    }
}

最佳答案

这必须使用反射来完成。

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

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

如果类型始终是动态的,将 ToObject 更改为采用 Type 作为参数的常规非泛型方法可能会容易得多。


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

我建议您考虑其他方法来处理这个问题。

关于c# - 使用动态类型调用泛型扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7208101/

相关文章:

c# - 如何提取visual studio项目模板图标?

c# - 正则表达式返回匹配前的单词

Java 泛型,无法从 E 转换为 E

haskell - Hindley-Milner 算法 : using types to ensure bindings are applied

types - GoLang 类型开关中变量 "t"的实际类型是什么?

c# - String.Join 返回 × 而不是次数?

c# - 如何使用 linq 从嵌套字典中选择所有值?

java - 如何使用泛型实现 Hibernate DAO

java - 重写方法中的泛型

swift - 在 Swift 中使用 IOPSNotificationCreateRunLoopSource 创建一个 CFRunLoopSourceRef