ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 在运行时使用新的匿名类型创建lambda表达式

2019-05-29 12:56:13  阅读:549  来源: 互联网

标签:c reflection entity-framework expression-trees anonymous-types


我想调用一个需要这样的参数的方法:

Expression<Func<sometype, 'a>> expr

我需要在运行时构造这个参数,因为我不知道之前的匿名类型是什么样的;它可以有任何数量的字段:

x => new { a=x.a, b=x.b, c=x.c, etc... }

我可以在运行时创建一个类型具有相同的’签名'(这是正确的单词吗?)作为所需的匿名类型,但问题是:如何在运行时从那个构造这个lambda表达式?特别是Expression.New是烦我的,因为我需要传递一个构造函数信息给它,我必须从一个现有的类型(它确实可以是一个匿名类型,但我不能在运行时创建一个匿名类型.或者在那里一种方法吗?).

更新(评论中要求的一些上下文)

我想调用的方法是:

DependentNavigationPropertyConfiguration.HasForeignKey<TKey>(Expression<Func<TDependentEntityType, TKey>> foreignKeyExpression)

我想这样做的原因是自动为从某个基类继承的实体创建一个导航属性,包括该外键中该基类的键.因为实体可以有多个任何类型的键字段,所以TKey类型只在运行时才为我所知.

解决方法:

使用单独的方法:

public static void Main()
{
    var myExpression = Express(str => new { 
        String = str, 
        Length = str.Length 
    });

    // We can compile/use it as well...
    var compiledExpression = myExpression.Compile();
    var anonymousOutput = compiledExpression("Input String");

    Console.WriteLine(anonymousOutput.String); // Output: Input String
    Console.WriteLine(anonymousOutput.Length); // Output: 12

    Debug.WriteLine(myExpression); // Output: "str => new <>f__AnonymousType0`2(String = str, Length = str.Length)"
    Console.ReadLine();
}


static Expression<Func<String, T>> Express<T>(Expression<Func<String, T>> expression)
{
    return expression;
}

但请注意,必须事先知道起始类型(在我的示例中为String).

更新:

既然你想要做的是动态创建一个类型,我会给你一个如何做到这一点的简单例子.

public static void Main()
{
        // Create an anonymous type with two fields
    Type myAnonymousType = CreateNewType<String, Int32>();
    dynamic myAnon = Activator.CreateInstance(myAnonymousType);

    myAnon.FieldA = "A String";
    myAnon.FieldB = 1234;


    Console.WriteLine(myAnon.FieldA); // Output : "AString"
    Console.WriteLine(myAnon.FieldB); // Output : 1234
    Console.ReadLine();
}

public static Type CreateNewType<TFieldTypeA, TFieldTypeB>()
{
    // Let's start by creating a new assembly
    AssemblyName dynamicAssemblyName = new AssemblyName("MyAsm");
    AssemblyBuilder dynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("MyAsm");

    // Now let's build a new type
    TypeBuilder dynamicAnonymousType = dynamicModule.DefineType("MyAnon", TypeAttributes.Public);

    // Let's add some fields to the type.
    FieldInfo dynamicFieldA = dynamicAnonymousType.DefineField("FieldA", typeof(TFieldTypeA), FieldAttributes.Public);
    FieldInfo dynamicFieldB = dynamicAnonymousType.DefineField("FieldB", typeof(TFieldTypeB), FieldAttributes.Public);

    // Return the type to the caller
    return dynamicAnonymousType.CreateType();
}

如您所见,这有点复杂.如果你想进一步研究这个话题,请务必参考Reflectoin.Emit.

标签:c,reflection,entity-framework,expression-trees,anonymous-types
来源: https://codeday.me/bug/20190529/1178135.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有