2012-01-27 82 views
4

我想一些技術來自動替換下面的代碼:如何通過添加屬性來警告未經初始化訪問屬性?

[WarnIfGetButUninitialized] 
public int MyProperty {get; set; } 

有了這個:

/// <summary> 
/// Property which warns you if its value is fetched before it has been specifically instantiated. 
/// </summary> 
private bool backingFieldIsPopulated = false; 
private int backingField; 
public int MyProperty { 
    get 
    { 
     if (backingFieldIsPopulated == false) 
     { 
      Console.WriteLine("Error: cannot fetch property before it has been initialized properly.\n"); 
      return 0; 
     } 
     return backingField; 
    } 
    set { 
     backingField = value; 
     backingFieldIsPopulated = true; 
    } 
}  

我寧願在編譯時有效的解決方案,因爲反射緩慢。我知道面向方面編程(AOP)會這樣做(例如PostSharp和CciSharp),但如果有其他方法可以實現這一點,我會很感興趣。

更新

參見How to use PostSharp to warn if a property is accessed before it has been initialized?其具有鏈接到演示使用PostSharp的技術中的一些示例代碼。

+3

我說你最簡單的選擇是使用PostSharp或統一的IoC它可以做有限的AOP。 – 2012-01-27 12:46:11

回答

2

屬性簡單元數據添加到類和類成員 - 它們本身什麼都不做。

在裝飾成員上完成的操作是通過反射完成的 - 在某些現有工具中對此有一些支持,但不會對定製屬性提供這種支持。

總之 - 如果編譯器不支持它,你不能在編譯時檢查屬性。

但是,您可以創建自己的code snippets,以使代碼更容易編寫和創建。

+0

我可以使用任何面向方面編程(AOP)實用程序(如PostSharp或CciSharp)來執行此操作。問題是 - 如何? – Contango 2012-01-27 12:50:36

+0

@Gravitas - 是的,雖然這是一個_extra_步驟_before_彙編(和我的經驗,PostSharp是相當緩慢)。 – Oded 2012-01-27 12:51:44

+0

我假設你的意思是在編譯時稍慢(但在運行時相同)。它是不是直接將IL注入到編譯後的程序集中,所以最終的結果與你自己編寫它的結果是一樣的? – Contango 2012-01-27 12:56:43

0

只有一些屬性通過編譯來檢查。 ObsoleteAttribute和ConditionalAttribute是其中的兩個。 使用Resharper,你可以得到這樣的警告。我不知道任何其他工具可以做到這一點。

0

你可以做一個類似於.NET的Lazy的實現,但是這會在使用這個屬性時需要更多的單詞。事情是這樣的非線程安全的例子:

public class WarnIfGetButUninitialized<T> 
{ 
    T _property; 
    public T Value 
    { 
     get 
     { 
      if(_property == null) 
      { 
       Console.WriteLine("Error: cannot fetch property before it has been initialized properly.\n"); 
       return default(T); 
      } 
      return _property; 
     } 
     set { _property = value; } 
    } 
}