在方法中传递对派生对象的引用时出错

时间:2009-11-03 05:03:16

标签: c# .net inheritance reference

在c#中我试图实现一个方法,我可以用它将数据绑定到我传递给它的任何控件(当然,控件是从数据绑定控件对象派生的)

给出方法

 public void CTLBindData(ref DataBoundControl ctl){ ... }

尝试将派生控件传递给函数时出错 例如以下代码

DropDownList lister = new DropDownList();  
CTLBindData(ref lister);

生成转换错误

好的我可以接受,但以下让我困惑(可能是因为我习惯了c ++而不是c#)

CTLBindData(ref (DataBoundControl)lister);

在这种情况下,我收到错误 “ref或out参数必须是可赋值变量”

为了澄清,Dropdownlist继承自继承自DataBoundControl的列表控件

这对我没有意义我应该能够传递从数据绑定控件派生的任何对象。似乎显式的类型转换导致了这个问题。

关于我做错了什么的线索?

DC

3 个答案:

答案 0 :(得分:7)

在调用方法之前进行强制转换:

DataBoundControl countrol = (DataBoundControl)lister;
CTLBindData(ref control);

C#要求任何ref参数属于 exact 类型(无多态性),并且该类型的引用必须是可分配的。这就是您必须在单独的步骤中通过显式强制转换创建引用的原因,因此该方法具有可以为其赋值的正确类型的引用。

有关此主题的更多信息,请参阅Eric Lippert的Why do ref and out parameters not allow type variation?

  

如果您的方法采用“X”   然后你必须传递一个表达式   输入X或可转换为X的东西。   比方说,派生类型的表达式   从X.但如果你有一个方法   拿一个“ref X”,你必须通过一个   ref为类型为X的变量,句点。   这是为什么?为什么不允许类型   和非参考电话一样,会有所不同吗?

答案 1 :(得分:0)

Andrew Hare是正确的,但在这种情况下,您甚至可能不想使用ref。 C#中的对象已经通过引用*传递。 (与值类型相反,除非使用ref关键字,否则不会通过引用传递。)很少有案例我能够想到您实际需要以这种方式传递引用类型的位置。如果没有ref,您的原始代码应该可以正常运行。

**不是真的,但如果你来自非C#背景,那么就更容易理解。该引用实际上是按值传递的。 There is an excellent article关于这一切是如何运作的。{

答案 2 :(得分:0)

安德鲁·黑尔(Andrew Hare)回答得很好。

您的对象必须里面有东西才能使用 REF OUT 。例如:可以为空。

DropDownList lister = new DropDownList();
lister = null;   
CTLBindData(ref lister);