2017-01-23 46 views
1

我需要爲函數創建屬性,該函數將根據給定的名稱創建文件之前調用函數或者即使存在沒有調用函數
例如,如果我有屬性附加傷害[some("C:\\hello.txt")]功能:如何在創建文件之前或不創建文件的函數中創建屬性

[some("C:\\hello.txt")] 
private void foo() 
{ 
    // do something 
} 

當我將運行該應用程序會創建這個文件:調用函數或即使(「C:\ hello.txt的」)以前的功能沒有呼叫..

我有兩種方法的嘗試:
1.在構造
2.創建與反思文件創建文件。

但他們都沒有爲我工作。

第一次嘗試(含構造函數):
我試圖在構造函數中每次創建該文件有一個新的屬性。
在這種方法中,我試圖在輸入Main函數之前創建文件。
它解析函數時會查找屬性並創建文件。
預期:應創建
兩個文件:
1. C:\ hello.txt的
2. C:\ bye.txt

在現實=>沒有發生。

[some("C:\\hello.txt")] 
private void foo() 
{ 
    // do something 
} 

[some("C:\\bye.txt")] 
private void foo() 
{ 
    // do something 
} 

public class someAttribute : Attribute 
{ 
    public someAttribute(string fileToCreate) 
    { 
     // File.Create(fileToCreate); 
     Console.WriteLine("Create file " + fileToCreate); 
    } 
} 

static void Main(string[] args) 
{ 
    // something 
} 

第二個嘗試(與反射):
預期:
一個文件應該被創建:
1. C:\ hello.txt的

在現實=> 「類型」 的變量是空的,沒有任何東西正在創建。

[some(fileToCreate = "C:\\hello.txt")] 
private void foo() 
{ 
    // do something 
} 

public class someAttribute : Attribute 
{ 
    public string fileToCreate {get; set;} 
} 

static void Main(string[] args) 
{ 

    var types = from t in Assembly.GetExecutingAssembly().GetTypes() 
       where t.GetCustomAttributes<someAttribute>().Count() > 0 
       select t; 
    foreach(var t in types) // types is null 
    { 
     string n = t.Name; 
     foreach(var p in t.GetProperties()) 
     { 
      // File.Create(fileToCreate) 
      Console.WriteLine(p.fileToCreate); 
     } 
    } 

} 
+0

您是否擁有屬性函數可能屬於的類的列表?如果是這樣,那麼這個問題可能是有用的:http://stackoverflow.com/questions/2831809/how-would-i-use-reflection-to-call-all-the-methods-that-has-a-certain-定製ATT。要將屬性附加到方法中,您需要對方法所屬的類使用反射。 – purplecat

+0

關於您的第一次嘗試(將創建文件代碼放入屬性的構造函數中),它不起作用的原因在此處得到解答:http://stackoverflow.com/questions/1168535/when-is-a-custom-attributes -constructor運行#1168590。 – purplecat

回答

1

,因爲當檢查屬性見When is a custom attribute's constructor run?瞭解更多詳細信息屬性的構造函數運行你的第一次嘗試沒有成功。它不會僅僅由於方法在代碼中具有該屬性而運行。因此需要反射來獲取具有所需屬性的方法列表。

您的第二次嘗試接近,但沒有奏效,因爲您只查看了附加到類類型的屬性。您需要進一步查看類中的方法。

我想出了一個解決方案,但要警告它可能會影響性能,因爲它會查看鏈接到項目的程序集中的每種類型和方法。您可能希望限制程序集只有那些您可能期望擁有someAttribute的程序集。有關如何執行此操作的一些示例,請參閱C#: List All Classes in Assembly

static void Main() 
{ 
    var methods = AppDomain.CurrentDomain.GetAssemblies() 
        //Get a sequence of all types in the referenced assemblies 
        .SelectMany(assembly => assembly.GetTypes()) 
        //Get a sequence of all the methods in those types. 
        //The BindingFlags are needed to make sure both public and non-public instance methods are included. 
        //Otherwise private methods are skipped. 
        .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) 
        //And finally, filter to only those methods that have someAttribute attached to them 
        .Where(method => Attribute.IsDefined(method, typeof(someAttribute))); 

    foreach (MethodInfo methodInfo in methods) 
    { 
     IEnumerable<someAttribute> SomeAttributes = methodInfo.GetCustomAttributes<someAttribute>(); 
     foreach (var attr in SomeAttributes) 
     { 
      //Here, you can create the file. 
      Console.WriteLine(attr.fileToCreate); 
     } 
    } 
} 
+0

謝謝你!有用。我只是做了一點改變,就像你說過的只有一個裝配表演一樣。這是我做的小改動:var methods = Assembly.GetExecutingAssembly()。GetTypes() .SelectMany(t => t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) 。Where(method => Attribute.IsDefined(method,typeof(someAttribute))); – E235