找出某個namespace下所有類別裡面有哪些類別的哪些屬性不是單純的get set | find out class that have not simple getter setter property in specific name space

需求描述

因為要做重構,需要找出有哪些邏輯是藏在 DTO 裡面的,
但 DTO 類別檔又很多,不想一個個找
所以就想寫個 console 程式來撈

做法

首先把要撈的 DLL 跟他相依的 DLL 都複製到要執行的排程執行檔輸出資料夾(通常是 bin\debug)

以下程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Worker {
public void DoWork () {
System.Reflection.Assembly service = Assembly.LoadFile (@"<你要找的namespace所在的dll的絕對路徑>.dll");
Type[] typelist = service.GetTypes ();
//你的類別名稱的特徵,例如找DTO就結尾是DTO
var nameHaveDtoTypes = typelist.Where (x => x.Name.ToUpper ().EndsWith ("DTO"));
foreach (var typeitem in nameHaveDtoTypes) {
if (typeitem.GetProperties ().Any (prop => !MightBeCouldBeMaybeAutoGeneratedInstanceProperty (prop))) {
//印到畫面跟輸出視窗
foreach (var prop in typeitem.GetProperties ().Where (prop => !MightBeCouldBeMaybeAutoGeneratedInstanceProperty (prop))) {
Console.WriteLine ($"{typeitem.Name},{prop.Name}");
System.Diagnostics.Debug.WriteLine ($"{typeitem.Name},{prop.Name}");
}
}
}
}
public bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty (PropertyInfo info) {
bool mightBe = info.GetGetMethod ().GetCustomAttributes (typeof (CompilerGeneratedAttribute), true).Any ();
if (!mightBe) {
return false;
}
bool maybe = info.DeclaringType
.GetFields (BindingFlags.NonPublic | BindingFlags.Instance)
.Where (f => f.Name.Contains (info.Name))
.Where (f => f.Name.Contains ("BackingField"))
.Where (f => f.GetCustomAttributes (typeof (CompilerGeneratedAttribute), true).Any ())
.Any ();
return maybe;
}
}

參考:
1.LINE 群大神指點關鍵字CompilerGeneratedAttribute
這個是指在編譯成 DLL 時,單純 getter setter 的屬性上面會有這個 tag
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.compilergeneratedattribute.aspx

2.How to find out if a property is an auto-implemented property with reflection?
https://stackoverflow.com/questions/2210309/how-to-find-out-if-a-property-is-an-auto-implemented-property-with-reflection?lq=1