递归拉取所有构造函数选项?

Set*_*hen 4 c# recursion constructor

假设我有一个包含一个对象的对象,每个对象都有一个或多个构造函数:

 Foo(int p1, Bar p2);
 
 Bar(String p3, String p4);

 Bar(int p5, int p6);    
Run Code Online (Sandbox Code Playgroud)

我想在 UI 中显示构建Foo需要哪些参数。我认为有以下三种选择:

int p1, Bar p2
Run Code Online (Sandbox Code Playgroud)

或者

int p1, String p3, String p4
Run Code Online (Sandbox Code Playgroud)

或者

int p1, int p5, int p6
Run Code Online (Sandbox Code Playgroud)

显然,由于嵌套了更多的对象,它变得更加复杂。有没有办法拉出所有这些选项?在 C# 中怎么样?如果您可以展示如何在上面给出了选项 2 或 3 的情况下动态构建Foo,则加分。

dcg*_*dcg 7

您可以(如评论中所建议的)使用反射和递归来实现您想要的。下降到另一个递归级别的标准取决于您。我已经实现了这些类来模仿你的类:

public class Foo
{
    public Foo(int p1, Bar p2)
    { }
}
public class Bar
{
    public Bar(string p3, string p4)
    { }
    public Bar(int p5, int p6)
    { }
}
Run Code Online (Sandbox Code Playgroud)

然后我实现了这个递归方法来打印可能的结构:

public static void PrintConstructors(Type t, string currentOutput)
{
    foreach (var ctor in t.GetConstructors())
    {
        var construct = currentOutput;
        foreach (var param in ctor.GetParameters())
        {
            if (param.ParameterType.IsClass && param.ParameterType != typeof(string))
            { PrintConstructors(param.ParameterType, construct); }
            construct += $"{param.ParameterType} {param.Name}, ";
        }
        if (!string.IsNullOrEmpty(construct))
        { Console.WriteLine(construct.TrimEnd(',', ' ')); }
    }
}
Run Code Online (Sandbox Code Playgroud)

调用PrintConstructors(typeof(Foo), "");产生以下输出:

System.Int32 p1, System.String p3, System.String p4
System.Int32 p1, System.Int32 p5, System.Int32 p6
System.Int32 p1, ConsoleApp.Bar p2
Run Code Online (Sandbox Code Playgroud)

编辑:当构造函数中有多个复杂类型时,另一种选择是(不检查循环依赖项,如@Micha?Turczyn 所述):

System.Int32 p1, System.String p3, System.String p4
System.Int32 p1, System.Int32 p5, System.Int32 p6
System.Int32 p1, ConsoleApp.Bar p2
Run Code Online (Sandbox Code Playgroud)

假设你更新的构造函数Foo(int p1, Bar p2)Foo(int p1, Bar p2, string s1, Bar y)你得到的输出:

public static IEnumerable<string> GetConstructs(Type t)
{
    foreach (var ctor in t.GetConstructors())
    {
        var constructs = new List<string>() { "" };
        foreach (var param in ctor.GetParameters())
        {
            if (param.ParameterType.IsClass && param.ParameterType != typeof(string))
            {
                var newConstructs = new List<string>();
                foreach (var _construct in GetConstructs(param.ParameterType))
                {
                    foreach (var construct in constructs)
                    { newConstructs.Add(construct + $"{param.ParameterType } ({_construct}) {param.Name}, "); }
                }
                constructs = newConstructs;
            }
            else
            {
                for (var i = 0; i < constructs.Count; i++)
                { constructs[i] += $"{param.ParameterType} {param.Name}, "; }
            }

        }
        foreach (var construct in constructs)
        { yield return construct.TrimEnd(',', ' '); }
    }
}
Run Code Online (Sandbox Code Playgroud)

是:

System.Int32 p1, ConsoleApp.Bar (System.String p3, System.String p4) p2, System.String s1, ConsoleApp.Bar (System.String p3, System.String p4) y
System.Int32 p1, ConsoleApp.Bar (System.Int32 p5, System.Int32 p6) p2, System.String s1, ConsoleApp.Bar (System.String p3, System.String p4) y
System.Int32 p1, ConsoleApp.Bar (System.String p3, System.String p4) p2, System.String s1, ConsoleApp.Bar (System.Int32 p5, System.Int32 p6) y
System.Int32 p1, ConsoleApp.Bar (System.Int32 p5, System.Int32 p6) p2, System.String s1, ConsoleApp.Bar (System.Int32 p5, System.Int32 p6) y
Run Code Online (Sandbox Code Playgroud)