gpt4 book ai didi

c# - 在运行时创建具有新匿名类型的 lambda 表达式

转载 作者:太空狗 更新时间:2023-10-30 01:06:00 26 4
gpt4 key购买 nike

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

Expression<Func<sometype, 'a>> expr

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

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

我可以在运行时创建一个类型,它与所需的匿名类型具有相同的“签名”(这是正确的词吗?),但问题是:如何在运行时从中构造此 lambda 表达式?特别是 Expression.New 困扰着我,因为我需要将一个 constructorInfo 传递给它,我必须从现有类型(它确实可以是匿名类型,但我不能在运行时创建匿名类型。或者有有办法吗?)。

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

我要调用的方法是:

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();
}

如您所见,这有点复杂。如果您想进一步研究该主题,请务必引用 Reflection.Emit

关于c# - 在运行时创建具有新匿名类型的 lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16838136/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com