由于本人经常在牛客网(http://www.nowcoder.com 或者 http://www.newcoder.com)上刷题,因为根据他们的规则,需要经常建立很多的项目,便于进行测试,这样很不易方便维护,后来了解到反射,就自己写了一个类,在窗体上进行选择需要运行哪个类,这样方便自己维护刷题的代码。个人牛客主页:http://www.nowcoder.com/415611
关于反射的一些信息,读者自行了解。我这里把我自己封装的代码贴出来,供大家使用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ChoiceApplicationToRun
{
public class ApplicationChooser
{
const string RUNNUMBERKEY_Str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void Run(Type type, string[] args)
{
Assembly assembly = type.Assembly;
List<MethodBase> entryMethodPointList = new List<MethodBase>();
foreach (Type t in assembly.GetTypes())
{
if (t == type)
{
continue;
}
MethodBase entryMethodPoint = GetMethodEntryPoint(t);
if (entryMethodPoint != null)
{
entryMethodPointList.Add(entryMethodPoint);
}
}
entryMethodPointList.Sort(delegate(MethodBase method1, MethodBase method2) { return method1.DeclaringType.Name.CompareTo(method2.DeclaringType.Name); });
if (entryMethodPointList.Count == 0)
{
Console.WriteLine("没有找到方法的入口点.点击任意键退出");
Console.ReadLine();
return;
}
for (int i = 0; i < entryMethodPointList.Count; i++)
{
Console.WriteLine("{0}:{1}", RUNNUMBERKEY_Str[i], GetEntryMethodPointName(entryMethodPointList[i]));
}
Console.WriteLine();
Console.Write("请输入运行的代号:");
Console.Out.Flush();
string input = Console.ReadLine();
if (input == null)
{
return;
}
int entry = 0;
if (!int.TryParse(input, out entry))
{
Console.WriteLine("无效的输入");
}
else
{
try
{
MethodBase main = entryMethodPointList[entry];
main.Invoke(null, main.GetParameters().Length == 0 ? null : new object[] { args });
}
catch (Exception ex)
{
Console.WriteLine("出现异常:{0}",ex);
}
}
Console.WriteLine();
Console.WriteLine("点击任意键退出");
Console.ReadLine();
}
/// <summary>
/// 方法的名称
/// </summary>
/// <param name="methodBase"></param>
/// <returns></returns>
private static object GetEntryMethodPointName(MethodBase methodBase)
{
Type type = methodBase.DeclaringType;
object[] descripts = type.GetCustomAttributes(typeof(DescriptionAttribute),false);
return descripts.Length == 0 ? type.Name : string.Format("{0}{1}",type.Name,((DescriptionAttribute)descripts[0]).Description);
}
/// <summary>
/// 返回类中一个方法的入口点,或者如果没有就返回null。
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
internal static MethodBase GetMethodEntryPoint(Type type)
{
if (type.IsGenericTypeDefinition || type.IsGenericType)
{
return null;
}
BindingFlags anyStatic = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
MethodInfo[] methods = type.GetMethods(anyStatic);
MethodInfo parameterless = null;
MethodInfo stringArrayParam = null;
foreach (MethodInfo item in methods)
{
if (item.Name != "Main")
{
continue;
}
if (item.IsGenericMethod || item.IsGenericMethodDefinition)
{
continue;
}
ParameterInfo[] parms = item.GetParameters();
if (parms.Length == 0)
{
parameterless = item;
}
else
{
if (parms.Length == 1 && !parms[0].IsOut && !parms[0].IsOptional && parms[0].ParameterType == typeof(string[]))
{
stringArrayParam = item;
}
}
}
return stringArrayParam ?? parameterless;
}
}
}
这样灵感来自于阅读《C# in Depth》的代码而来。
我自己的测试项目如下:
运行时调用的代码在Program中:
class Program
{
[STAThread] //记得添加标记
static void Main(string[] args)
{
ChoiceApplicationToRun.ApplicationChooser.Run(typeof(Program), args);
}
}
以其中的Decrypt类中测试的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NowCoderProgrammingProject
{
class Decrypt
{
static void Main()
{
Process();
}
static void Process()
{
string line = null;
while ((line = Console.ReadLine()) != null)
{
char[] strArr = line.ToCharArray();
List<string> res = new List<string>();
Permulation(0, strArr, res);
res.Sort();
foreach (var item in res)
{
Console.WriteLine(item);
}
}
}
static void Permulation(int step, char[] strArr, List<string> ans)
{
if (step == strArr.Length - 1)
{
ans.Add(new string(strArr));
}
for (int i = step; i < strArr.Length; i++)
{
Swap(strArr, step, i);
Permulation(step + 1, strArr, ans);
Swap(strArr, step, i);
}
}
static void Swap(char[] chArr, int i, int j)
{
char tmp = chArr[i];
chArr[i] = chArr[j];
chArr[j] = tmp;
}
}
}
以后再添加的类中保证有static Main 这个方法就能被搜索到。运行的截图如下:
需要特别注意的是,在Program.cs所在的项目中设置起始项目,要不然编译报错。
设置如下: