1

コード内にあるジェネリック クラスのラッパー クラスを (リフレクションを使用して) 生成できるコード ジェネレーター (できればソースを使用) を探しています。

少し検索しましたが、ここで必要なことを行うものを見つけることができないようですので、自分で書き始める前にここで質問すると思いました. 最終的には、おそらく自分で書く必要がありますが、誰かがすでにこのようなものを書いている場合は、少なくとも有利なスタートを切りたいと思います。

何をしたいのかを説明するのは少し難しいですが、ジェネレーターは、ラッパーを生成するジェネリッククラスを指定できるようにする必要があります。ジェネリック クラスの where 制約に基づいて、どれが適合するかを判断するために指定した DLL の型を調べる必要があります。「生成されたコード」セクションの出力例を使用して、linqpad でいくつかのサンプル コードを作成しました。ご覧のとおり、ジェネリック クラスで指定された制約に基づいて、クラスのすべての組み合わせを生成します。

なぜ私はこれをしたいのですか?それぞれに多くの型パラメーター (多くは 10 個以上の型パラメーターを持つ) を持つかなりの数のジェネリック クラスがあり、クライアント コードを簡素化する必要があります (これには、ブランケットがすべてを生成するコード ジェネレーターと共にいくつかのカスタム作業も必要になります)。組み合わせは可能ですが、私は対処できます)。それが完了したら、基礎となるジェネリック クラスをリファクタリングして (クライアント コードに影響を与えずに) 単純化し、現時点で必要な型パラメーターの数を減らすことができますが、これはこの段階では完全には不可能です。

void Main()
{
    var x = new GenBothFooAgainBarAgain();
    var y = new GenFFoo();
    var z = new GenFFooAgain();
    var a = new GenBothWithChildFooBarFooChild();
    var b = new GenBothWithChildFooBarAgainFooChild();
}

//////////////////////////////////Generated code ////////////////////////////////////
public class GenBothFooBar : GenBoth<Foo, Bar> {}
public class GenBothFooAgainBar : GenBoth<FooAgain, Bar> {}
public class GenBothFooBarAgain : GenBoth<Foo, BarAgain> {}
public class GenBothFooAgainBarAgain : GenBoth<FooAgain, BarAgain>{}
public class GenFFoo : GenF<Foo>{}
public class GenFFooAgain : GenF<FooAgain>{}

public class GenBothWithChildFooBarFooChild : GenBothWithChild<Foo, Bar, FooChild> {}
//public class GenBothWithChildFooAgainBarFooChild : GenBothWithChild<FooAgain, Bar, FooChild> {} - illegal - Don't generate this as FooChild doesn't inherit from FooAgain
public class GenBothWithChildFooBarAgainFooChild : GenBothWithChild<Foo, BarAgain, FooChild> {}
//public class GenBothWithChildFooAgainBarAgainFooChild : GenBothWithChild<FooAgain, BarAgain, FooChild>{} - illegal - Don't generate this as FooChild doesn't inherit from FooAgain


//////////////////////////////////Generated code ////////////////////////////////////

public class Foo : IFoo
{
    public string foo {get; set;}
}

public class FooChild : Foo, IFooChild
{
    public string fooChild {get; set;}
}

public class Bar : IBar
{
    public string bar {get; set;}
}

public class FooAgain : IFoo
{
    public string foo {get; set;}
}

public class BarAgain : IBar
{
    public string bar {get; set;}
}

public class GenF<F>
where F: class, IFoo, new()
{

}

public class GenBoth<F, B>
where F: class, IFoo, new()
where B: class, IBar, new()
{

}

public class GenBothWithChild<F, B, FChild>
where F: class, IFoo, new()
where B: class, IBar, new()
where FChild: class, F, IFooChild, new()
{

}

public interface IFooChild
{
    string fooChild {get; set;}
}

public interface IFoo
{
    string foo {get; set;}
}

public interface IBar
{
    string bar {get; set;}
}
4

1 に答える 1