【问题标题】:Get class from Type with Reflection and call a generic constructor with Type in C#使用反射从 Type 中获取类并在 C# 中使用 Type 调用泛型构造函数
【发布时间】:2014-01-21 17:04:35
【问题描述】:

我正在使用 Dapper,我想遍历我的模型类并为任何具有用 ColumnAttribute 装饰的字段的类设置类型映射。

public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
{
    public static readonly string ColumnAttributeName = "ColumnAttribute";

    public ColumnAttributeTypeMapper()
        : base(new SqlMapper.ITypeMap[]
        {
            new CustomPropertyTypeMap(typeof (T), SelectProperty),
            new DefaultTypeMap(typeof (T))
        })
    {
    }
    // implementation of SelectProperty and so on...
    // If required, full implementation is on https://gist.github.com/senjacob/8539127
}

在我的模型类库中,我正在遍历所有可能的类型;现在我需要使用该类型的类调用泛型 ColumnAttributeTypeMapper&lt;T&gt; 构造函数。

using System.Web;
using Dapper;

[assembly : PreApplicationStartMethod(typeof(Model.Initiator), "RegisterTypeMaps")]

namespace Model
{
    class Initiator
    {
        public static void RegisterTypeMaps()
        {
            var mappedTypes = Assembly.GetAssembly(typeof (Initiator)).GetTypes().Where(
                f =>
                f.GetProperties().Any(
                    p =>
                    p.GetCustomAttributes(false).Any(
                        a => a.GetType().Name == ColumnAttributeTypeMapper<dynamic>.ColumnAttributeName)));

            // I want to skip registering each class manually :P
            // SqlMapper.SetTypeMap(typeof(Model1), new ColumnAttributeTypeMapper<Model1>());
            // SqlMapper.SetTypeMap(typeof(Model2), new ColumnAttributeTypeMapper<Model2>());

            foreach (var mappedType in mappedTypes)
            {
                SqlMapper.SetTypeMap(mappedType, new ColumnAttributeTypeMapper<mappedType>());
            }
        }
    }
}

如何将类从类型而不是类型“mappedType”传递给new ColumnAttributeTypeMapper&lt;classof(mappedType)?&gt;()

我找到了this as a similar question,但我需要使用Type 调用泛型构造函数而不是泛型方法。

如果不能,请说明原因?

回答

这就是 Tom 建议的映射工作方式。

var mapper = typeof(ColumnAttributeTypeMapper<>);
foreach (var mappedType in mappedTypes)
{
    var genericType = mapper.MakeGenericType(new[] { mappedType });
    SqlMapper.SetTypeMap(mappedType, Activator.CreateInstance(genericType) as SqlMapper.ITypeMap);
}

【问题讨论】:

标签: c# generics reflection types dapper


【解决方案1】:

您将需要方法Type.MakeGenericType;用法如下:

var columnType = typeof(ColumnAttributeTypeMapper<>);
var genericColumn = columnType.MakeGenericType(new[] {typeof(mappedType)});
var instance = Activator.CreateInstance(genericColumn);

我写这篇文章时没有智能感知,只是略读了你的代码,所以请让我知道我是否犯了任何错误,我会纠正它们。

【讨论】:

    猜你喜欢
    • 2022-09-27
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多