2010-12-23 87 views
42

我收到上述錯誤並無法解決它。 我google了一下,但無法擺脫它。屬性或索引器不能作爲輸出或參數參數傳遞

場景:

我有類BudgetAllocate屬性爲預算是double類型的。

在我dataAccessLayer,

在我班的一個我試圖做到這一點:

double.TryParse(objReader[i].ToString(), out bd.Budget); 

這是引發此錯誤:

Property or indexer may not be passed as an out or ref parameter at compile time.

我甚至試過這樣:

double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget); 

Ev另外一些工作正常,層間引用也存在。

+0

在bd.Budget BD是類BudgetAllocate的對象。對不起我忘記了。 – Pratik 2010-12-23 13:02:12

+0

可能重複的[C#屬性和ref參數,爲什麼沒有糖?](http://stackoverflow.com/questions/529782/c-sharp-property-and-ref-parameter-why-no-sugar) – 2013-04-20 01:31:43

+0

可能的重複[通過泛型類型參數訪問屬性](http://stackoverflow.com/questions/3059420/accessing-properties-through-generic-type-parameter) – 2013-11-03 20:05:05

回答

16

不能使用

double.TryParse(objReader[i].ToString(), out bd.Budget); 

一些變量替換bd.Budget。

double k; 
double.TryParse(objReader[i].ToString(), out k); 
+5

爲什麼要使用一個額外的變量? – Pratik 2010-12-23 13:05:49

1

所以預算是一個屬性,是否正確?

首先將其設置爲局部變量,然後將屬性值設置爲該值。

double t = 0; 
double.TryParse(objReader[i].ToString(), out t); 
bd.Budget = t; 
7

將out參數到一個局部變量,然後設置變量爲bd.Budget

double tempVar = 0.0; 

if (double.TryParse(objReader[i].ToString(), out tempVar)) 
{ 
    bd.Budget = tempVar; 
} 

更新:直接從MSDN:

Properties are not variables and therefore cannot be passed as out parameters.

http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx

83

其他人已經給喲你的解決方案,但至於爲什麼這是必要的:屬性只是一個方法句法糖。

例如,當您使用getter和setter聲明一個名爲Name的屬性時,編譯器實際上會生成一個名爲get_Name()set_Name(value)的方法。然後,當您讀取並寫入此屬性時,編譯器會將這些操作轉換爲對這些生成的方法的調用。

當你考慮到這一點,你爲什麼不能將財產傳給作爲輸出參數是顯而易見的 - 你會實際上是一個引用傳遞到方法,而不是對象一個變量的引用,這是輸出參數所期望的。

索引器存在類似情況。

43

這是一個泄漏抽象的例子。屬性實際上是一種方法,得到集合索引器的訪問器被編譯爲get_Index()和set_Index方法。編譯器做了一個了不起的工作來隱藏這個事實,例如,它自動將一個賦值轉換爲一個屬性到相應的set_Xxx()方法。

但是,當你通過引用傳遞一個方法參數時,這會變得很糟糕。這要求JIT編譯器將一個指針傳遞給傳遞參數的內存位置。問題是,沒有一個,分配一個屬性的值需要調用setter方法。被調用的方法無法區分傳遞的變量和傳遞的屬性之間的區別,因此不知道是否需要方法調用。

值得注意的是,這實際上在VB.NET中起作用。例如:

Class Example 
    Public Property Prop As Integer 

    Public Sub Test(ByRef arg As Integer) 
     arg = 42 
    End Sub 

    Public Sub Run() 
     Test(Prop) '' No problem 
    End Sub 
End Class 

的VB.NET編譯器通過自動生成的運行方法這段代碼解決了這個,表示在C#:

int temp = Prop; 
Test(ref temp); 
Prop = temp; 

這是你可以使用,以及解決方法。不太清楚爲什麼C#團隊不使用相同的方法。可能是因爲他們不想隱藏潛在的昂貴的吸氣和呼吸。或者當制定者有改變屬性值的副作用時,你會得到完全不可知的行爲,他們會在分配後消失。 C#和VB.NET,C#之間的經典區別是「毫無意外」,VB.NET是「如果可以的話就讓它工作」。

5

的可能感興趣的 - 你可以寫你自己:

//double.TryParse(, out bd.Budget); 
    bool result = TryParse(s, value => bd.Budget = value); 
} 

public bool TryParse(string s, Action<double> setValue) 
{ 
    double value; 
    var result = double.TryParse(s, out value); 
    if (result) setValue(value); 
    return result; 
}