[C#]使用Reflection檢查指定類別是否含有預設建構子

[C#]使用Reflection檢查指定類別是否含有預設建構子

昨天在抽空調整一下專案程式碼,用Attribute與反射搭配的機制去做一些載入的動作,讓程式擴充時能專注在新加入的類別就好,程式啟動自行會用反射將該載入的載入。但由於目前尚未把現有的程式改的比較一致,每個類別的建構子不盡相同,因為我預期這些類別應該都要有預設的建構子,不夠的資料應該後續再透過別條路下去取得,所以這邊只先用反射載入含有預設建構子的類別,其它沒有預設建構子的類別就先照本來的路做些特殊處理,待後續再行重構。

 

要做偵測類別是否含有建構子,換句話說就是要想辦法取得該類別的預設ConstructorInfo。最簡單的作法就是用Type.GetConstructors取得所有的ConstructorInfo,然後找出不含參數的ConstructorInfo就可以了。

		{
			var type = typeof (T);
			foreach (var c in type.GetConstructors(BindingFlags.Instance | BindingFlags.Public))
			{
				if (c.GetParameters().Length ==0)
					return true;
			}
			return false;
		}

 

但這方法有點笨矬,比較好一點的作法應該是透過Type.GetConstructor去取得,帶入空的Type[]當作參數取得ConstructorInfo,當回傳的ConstructorInfo不為空則代表該類別有預設建構子。

		{
			var type = typeof (T);
			return type.GetConstructor(new Type[0]) != null;
		}

 

除了帶入空的Type[]外,我們也可以帶入Type.EmptyTypes,可以得到一樣的效果。

		{
			var type = typeof (T);
			return type.GetConstructor(Type.EmptyTypes) != null;
		}

 

最後附上比較完整的測試範例:

using System.Reflection;

namespace ConsoleApplication17
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine(HasDefaultConstructor1<TestClass1>());
			Console.WriteLine(HasDefaultConstructor2<TestClass1>());

			Console.WriteLine(HasDefaultConstructor1<TestClass2>());
			Console.WriteLine(HasDefaultConstructor2<TestClass2>());
		}

		private static Boolean HasDefaultConstructor1<T>()
		{
			var type = typeof (T);
			foreach (var c in type.GetConstructors(BindingFlags.Instance | BindingFlags.Public))
			{
				if (c.GetParameters().Length ==0)
					return true;
			}
			return false;
		}

		private static Boolean HasDefaultConstructor2<T>()
		{
			var type = typeof (T);
			return type.GetConstructor(Type.EmptyTypes) != null;
		}
	}

	internal class TestClass1
	{
		public TestClass1()
		{
				
		}

		public TestClass1(int arg1)
		{
				
		}
	}

	internal class TestClass2
	{
		public TestClass2(int arg1)
		{
				
		}
	}
}

 

運行結果如下:

image

 

Link