5

次のようなパラメーターを期待するメソッドを呼び出したい:

Expression<Func<sometype, 'a>> expr

以前は匿名型がどのようになるか分からないため、実行時にこのパラメーターを構築する必要があります。任意の数のフィールドを持つことができます。

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

実行時に、目的の匿名型と同じ「署名」(これは正しい言葉ですか?) を持つ型を作成できますが、問題は次のとおりです。特に Expression.New は、既存の型から取得する必要がある constructorInfo を渡す必要があるため、私を悩ませています (これは実際には匿名型である可能性がありますが、実行時に匿名型を作成することはできません。またはそこにあります)それを行う方法は?)。

更新(コメントで要求されたいくつかのコンテキスト)

呼び出したいメソッドは次のとおりです。

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

これを行う理由は、特定の基本クラスから継承するエンティティへのナビゲーション プロパティを自動的に作成し、その基本クラスのキーを外部キーに含めるためです。エンティティは任意の型の複数のキー フィールドを持つことができるため、TKey 型は実行時にしかわかりません。

4

3 に答える 3

15

別の方法を使用します。

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

于 2013-05-30T14:00:30.537 に答える
3

匿名型はコンパイラの機能です。コンパイル時にコンパイラにそれらを作成させない場合は、メタプログラミングを使用する必要があります-どちらかTypeBuilderまたは多分CSharpCodeProvider. タプルを使用したほうがよいかもしれません - 少なくとも作成は簡単です (Tuple.Create十分に簡単に使用できます)。

表情は・・・ - と入力することをお勧めしますExpression<Func<sometype, object>>。これは、どのような処方でも機能します。もちろん、を検査するコードExpressionは、実際の型が何であるかを確認できます。

于 2013-05-30T14:00:59.080 に答える