如何使用c#在运行时创建类的新实例?

时间:2016-07-08 22:28:11

标签: c# entity-framework entity-framework-6 entity

我有以下类,我在创建实例时传递了Entity Framework Model。

public class TableMapper<TSource>
{
    protected IQueryExtractor QueryExtractor { get; set; }
    protected string TableAliasPrefix { get; private set; } 

    public TableMapper(IQueryExtractor queryExtractor, string tableAliasPrefix = null)
    {
        QueryExtractor = queryExtractor;
        TableAliasPrefix = tableAliasPrefix;
    }

    public IReportRelation GetForeignRelation<TProperty>(Expression<Func<TSource, TProperty>> property)
    {
        return new ReportRelation
        {
            Column = GetReportColumn(null, Self, property),
            TableName = this.Table(),
            TableAlias = this.GetSqlAlias(),
            ModelType = typeof(TSource),
            QueryExtractor = this.QueryExtractor
        };
    }

    ...
    ...
    ...
}

我在上面的课程中调用了这个类似于

的其他类
var clientMapper = new TableMapper<Client>(QueryExtractor, "Client");
var = clientMapper.GetForeignRelation(x => x.Id);

请注意Client是实体框架6模型。

在我的GetForeignRelation方法中,我设置了Client<TSource>的类型,以便我可以在运行时创建TableMapper类的新实例。

以下是我尝试在运行时创建它的新实例时尝试做的事情。

var RunTimeModel = Activator.CreateInstance(relationsMapping.ModelType);
var RunTimeMapper = new TableMapper<RunTimeModel>(relationsMapping.QueryExtractor, relationsMapping.TableAlias);

但这给了我一个错误。

  

无法找到类型或命名空间名称RunTimeModel(是吗?   缺少using指令或程序集引用?)

如何在运行时正确创建同一个类的新实例?

3 个答案:

答案 0 :(得分:1)

您将获得带有

的TSource类名
typeof(TSource).Name

您应该可以使用以下命令创建实例:

var instance = Activator.CreateInstance(typeof(TSource));

只要类型在同一个程序集中 其他属性可用于获取完整命名空间

编辑:

此示例是否适用于您的scanario? 不得不删除你提供的代码,因为我不知道它背后是什么:)

class Program
{
    static void Main(string[] args)
    {
        var test = new TableMapper<A>();
        var fr = test.GetForeignRelation();
        var type = fr.ModelType;
        var newInstance = Activator.CreateInstance(type);
    }
}

public class TableMapper<TSource>
{

    public TableMapper()
    {
    }

    public ReportRelation GetForeignRelation()
    {
        return new ReportRelation
        {
            ModelType = typeof(TSource)
        };
    }
}

public class ReportRelation
{
    public Type ModelType { get; set; }
}

public class A
{
    public string Test { get; set; }
    public A()
    {
        Test = "Some string";
    }
}

答案 1 :(得分:0)

您无法将变量传递给类型参数

var RunTimeModel = Activator.CreateInstance(relationsMapping.ModelType);
var RunTimeMapper = new TableMapper<RunTimeModel>(relationsMapping.QueryExtractor, relationsMapping.TableAlias)

因为RunTimeModel不是类型而是变量。我认为你缺少正在使用的方法的目的。

答案 2 :(得分:0)

您可以使用以下代码来实例化您的泛型类型:

var RunTimeMapper = Activator.CreateInstance(typeof(TableMapper<>).MakeGenericType(new[] { relationsMapping.ModelType }), new[] { relationsMapping.QueryExtractor, relationsMapping.TableAlias });

但是,RunTimeMapper的返回值类型是object.I无法弄清楚如何将RunTimeMapper强制转换为它的实际类型。所以,它使用起来有点不方便。

的Referer:How to: Examine and Instantiate Generic Types with Reflection