上記のエラーが表示され、解決できません。私は少しグーグルで調べましたが、それを取り除くことはできません。
シナリオ:
プロパティが二重タイプの予算であるクラスBudgetAllocateがあります。
私のdataAccessLayerでは、
私のクラスの1つでこれをやろうとしています:
double.TryParse(objReader[i].ToString(), out bd.Budget);
これはこのエラーを投げています:
プロパティまたはインデクサーは、コンパイル時にoutまたはrefパラメーターとして渡されない場合があります。
私もこれを試しました:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
それ以外はすべて正常に機能しており、レイヤー間の参照が存在します。
使用できません
double.TryParse(objReader[i].ToString(), out bd.Budget);
bd.Budgetを何らかの変数に置き換えます。
double k;
double.TryParse(objReader[i].ToString(), out k);
他の人があなたに解決策を与えましたが、なぜこれが必要なのか:プロパティはmethodの単なる構文糖です。
たとえば、Name
というプロパティをゲッターとセッターで宣言すると、実際にはコンパイラーはget_Name()
およびset_Name(value)
というメソッドを生成します。次に、このプロパティを読み書きすると、コンパイラはこれらの操作を生成されたメソッドの呼び出しに変換します。
これを検討すると、プロパティを出力パラメーターとして渡すことができない理由が明らかになります。実際には、参照ではなくmethodへの参照を渡すことになります。 オブジェクト 変数。これは出力パラメーターが期待するものです。
インデクサーにも同様のケースがあります。
これは、漏れやすい抽象化の場合です。プロパティは実際にはメソッドであり、インデクサーのgetおよびsetアクセサーはget_Index()およびset_Indexメソッドにコンパイルされます。コンパイラーはその事実を隠す素晴らしい仕事をします。例えば、プロパティへの割り当てを対応するset_Xxx()メソッドに自動的に変換します。
しかし、参照によってメソッドパラメーターを渡すと、これはおしまいになります。それには、JITコンパイラーが、渡された引数のメモリー位置へのポインターを渡す必要があります。問題は、1つではなく、プロパティの値を割り当てるには、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#で表現されたRunメソッド用にこのコードを自動的に生成することにより、これを解決します。
int temp = Prop;
Test(ref temp);
Prop = temp;
どの回避策も使用できます。 C#チームが同じアプローチを使用しなかった理由はよくわかりません。おそらく、彼らは潜在的に高価なゲッターとセッターの呼び出しを隠したくなかったからでしょう。または、セッターにプロパティ値を変更する副作用がある場合に発生する完全に診断不可能な動作は、割り当て後に消えます。 C#とVB.NETの古典的な違いは、C#は「驚き」ではなく、VB.NETは「できる限り機能させる」ことです。
出力パラメーターをローカル変数に配置してから、変数をbd.Budget
に設定します。
double tempVar = 0.0;
if (double.TryParse(objReader[i].ToString(), out tempVar))
{
bd.Budget = tempVar;
}
更新:MSDNから直接:
プロパティは変数ではないため、出力パラメーターとして渡すことはできません。
おそらく興味がある-あなたはあなた自身を書くことができます:
//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;
}
これは非常に古い記事ですが、これを行うもっと便利な方法がありますが、私は知りませんでしたので、私は受け入れられたものを修正しています。
これはインライン宣言と呼ばれ、(ステートメントの使用のように)常に利用可能であるか、そのような場合にC#6.0またはC#7.0で追加された可能性がありますが、確かではありませんが、とにかく魅力のように動作します:
これのイネータ
double temp;
double.TryParse(objReader[i].ToString(), out temp);
bd.Budget = temp;
これを使って:
double.TryParse(objReader[i].ToString(), out double temp);
bd.Budget = temp;
予算は財産ですよね?
むしろ、最初にローカル変数に設定してから、プロパティ値をそれに設定します。
double t = 0;
double.TryParse(objReader[i].ToString(), out t);
bd.Budget = t;