2011-09-13 55 views
15

我有一個存儲庫類和服務類如下:字段初始值設定項無法引用非靜態字段,方法或屬性?

public class DinnerRepository 
{ 
    DinnerDataContext db = new DinnerDataContext(); 

    public Dinner GetDinner(int id) 
    { 
     return db.Dinners.SingleOrDefault(d => d.DinnerID == id); 
    } 

// Others Code   
} 



public class Service 
{ 
     DinnerRepository repo = new DinnerRepository(); 
     Dinner dinner = repo.GetDinner(5); 

// Other Code 
} 

這將引發錯誤:

A field initializer cannot reference the non-static field, method, or property.

儘管我已經intatiated的DinnerRepository類在服務揭露其方法GetDinner()類。這適用於下面的代碼。除此之外還有其他選擇嗎?還是標準做法?我不能在這裏使用靜態方法..

public class Service 
{ 

    public Service() 
    { 
     DinnerRepository repo = new DinnerRepository(); 
     Dinner dinner = repo.GetDinner(5); 
    } 

} 

回答

18

個人而言,我只希望初始化場在構造函數中:

public class Service 
{ 
    private readonly DinnerRepository repo; 
    private readonly Dinner dinner; 

    public Service() 
    { 
     repo = new DinnerRepository(); 
     dinner = repo.GetDinner(5); 
    } 
} 

注意,這是不一樣的,你在顯示底部的代碼的問題,因爲這只是宣佈本地變量。如果你只有想要局部變量,這很好 - 但如果你需要實例變量,那麼使用上面的代碼。

基本上,字段初始值設定項的功能是有限的。從C#4規範的部分10.5.5.2:

A variable initializer for an instance field cannot reference the instance being created. Thus it is a compile-time error to reference this in a variable initializer, because it is a compile-time error for a variable initializer to reference any instance member through a simple-name.

(即「因此」和「所以」輪看起來是錯誤的方式我 - 這是非法通過一個簡單的名稱來引用成員因爲它引用this - 我會Ping一下它的Mads - 但是這基本上是相關的部分)

+0

是的,現在的版本是這樣的:「因爲我們在'simple-name's上有編譯時錯誤,所以我們引用'this'是一個錯誤」,而不是其他方式。 – SWeko

+0

@JonSkeet這種行爲的原因是字段在構造函數之前被初始化。所以當你嘗試初始化字段時沒有實例成員。這就是爲什麼你不能在課堂實例化之前使用它們吧? – UfukSURMEN

+1

@UfukSURMEN:不是真的......對象已經存在,但它會引起一些相當難以理解的錯誤。 (有時候這很煩人,無可否認......) –

2

即使initializaton表情都保證在"textual order",它是一個實例非法字段初始化to access the this reference,你是隱式使用它在

Dinner dinner = repo.GetDinner(5); 

這相當於

Dinner dinner = this.repo.GetDinner(5); 

最好的做法IMHO,是保留字段初始化爲恆定值或一個簡單的new語句。任何比這更有趣的東西應該去一個構造函數。

相關問題