2016-07-28 18 views
-2

強いタイピングの利点を維持しながら、特定のことを動的に行うことができるようにコードを生成するメカニズムをハックしようとしています。Visual StudioとC#/ VB.NETでのコード生成によるメタプログラミングのハッキング

ここでは、私がしたいことの種類の例です。私はこのようなオブジェクトを持っている:

Class Fruits 
    Public Property Apple As System.Int32 
    Public Property Orange As System.Int32 
    Public Property Kiwi As System.Int32 
    ...quite a few others 
    Public Property Banana As System.Int32 
    Public Property Watermelon As System.Int32 
    Public Property Durian As System.Int32 
End Class 

と私はこのないいくつかのコードがあります。つまり

Dim dict = myEntity.ToDictionary() 
Dim myFruits = {"Apple", "Banana", "Cherry"} 

For Each fruit in myFruits 
    Dim fruitValue = dict(fruit) 
    doSomething(fruitValue) 
Next 

を、私は強く型付けされたクラスを持っていると私はプロパティにアクセスしたいですこれらのプロパティはコードで決定される文字列です。

私が避けたい問題は、Fruitsクラスが変更できることです。たとえば、Appleプロパティが削除されました。これは、コード生成やリファクタリングのために作成されたものである可能性があります。 それでループ内のコードが壊れていますが、コンパイラはこのことについて私に警告する方法がありません


これまでのところ、上記のコードは、これに相当します

fruitValue = item.Apple 
    doSomething(fruitValue) 

    fruitValue = item.Banana 
    doSomething(fruitValue) 

    fruitValue = item.Cherry 
    doSomething(fruitValue) 

私はこのコードを持っていたと私はAppleを削除した場合、私はコンパイルエラーを取得したいとすべてがうまくなります。

実際には、私の果物のリストにはもっと多くのアイテムがあるかもしれませんし、複雑なデザインタイムルールによって決定されるかもしれないので、それらをすべて書き出すことは非常に退屈で、維持するのは面倒です。私が欲しいもの


は、インライン、タイプセーフコードを生成するように設計時のVisual Studioで前処理されたコードを書くための方法です。

私は、テンプレート、そのテンプレートへの入力、およびコードファイルをスキャンし、部分クラスファイルで必要なコード生成を行うある種のAddInを指定できるシステムと構文を想像しています。私は簡潔で動的なコードを書くことができましたが、基本的なオブジェクトアクセスが変更された場合にコンパイラエラーを引き起こす明示的なプロパティアクセスに拡張する必要があります。

質問:これはどのように実装できますか?

+0

何が問題なのですか? –

+0

@KeithPayne:私は自分の質問をそのように表現するように更新しました。 –

+0

私はそれについて何も知らないが、私は "Roslyn"があなたが探しているものかもしれないと思う:https://github.com/dotnet/roslyn/wiki/Roslyn%20Overview – SSS

答えて

0

あなたが動的オブジェクトのすべてのプロパティを取得するには、このようなものを使用することができます

var fruits = new Fruits(); 
foreach (var prop in fruits.GetType().GetProperties()) 
{ 
    // Do stuff here 
} 

あなたはまだそれらを反復処理するオブジェクトのプロパティに上記のコードを更新し、この方法で、すべての

msdnを参照してください。より多くのため

+0

問題は、実行時に動的にプロパティにアクセスする方法ではなく、コンパイル時に静的に行うコードを生成して、コンパイラが存在しないプロパティを参照するエラーをキャッチできるようにする方法です。 –

0

あなたは反射を使用することができます。

public static object GetPropvalue(this object InputObject, string PropertyName) 
{ 
    Type type = InputObject.GetType(); 
    PropertyInfo p = type.GetProperty(PropertyName); 
    if (p != null) 
    { 
     return p.GetValue(InputObject); 
    } 
    else 
    { 
     return null; 
    } 
} 

が次にあなたが

foreach (var f in myFruits) 
{ 
    var fruitValue = myEntity.GetPropValue(f); 
    if (fruitValue != null) 
    { 
     doSomething(fruitValue)); 
    }  
} 
+0

問題は、実行時に動的にプロパティにアクセスする方法ではなく、コンパイル時に静的に行うコードを生成して、コンパイラが存在しないプロパティを参照するエラーをキャッチできるようにする方法です。 –

0

この例では、

をメタプログラミングすることなく、あなたのシナリオのためのコンパイル時で仕事をする操作を行うことができます。私は、プロパティの値を取得するために拡張メソッドを作成したいです

NameOf expressionFruitsクラスのダミーインスタンスを使用するコードです。

Dim dict = myEntity.ToDictionary() 

Dim dummy As New Fruits() 
Dim myFruits As New List(Of String) From 
{ 
    NameOf(dummy.Apple), 
    NameOf(dummy.Orange), 
    NameOf(dummy.Kiwi) 
} 

For Each fruit in myFruits 
    Dim fruitValue = dict(fruit) 
    DoSomething(fruitValue) 
Next 

これはあなたの説明のシナリオで動作します:Appleプロパティが削除されます場合 - コンパイラがエラーが発生します。

私の意見では、この回避策は、コードの臭い(ダミーインスタンスを使用)のように見えます。私は、あなたがあなたの問題についてもっと詳しく話すなら、より適切な解決策を得ることができると確信しています。

関連する問題