2010-12-23 79 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; 
}