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

问题描述 投票:3回答:3

在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

c# .net inheritance reference
3个回答
7
投票

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

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

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

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

如果你有一个带有“X”的方法,那么你必须传递一个X类型的表达式或者一个可转换为X的表达式。比如,一个从X派生的类型的表达式。但是如果你有一个方法需要一个“ref X” “,你必须将ref传递给X类型的变量,句点。这是为什么?为什么不允许类型变化,就像我们使用非ref调用一样?


0
投票

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

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


0
投票

Andrew Hare回答得非常好。

您的对象必须在内部使用REF或OUT。例如:可以为null。

DropDownList lister = new DropDownList();
lister = null;   
CTLBindData(ref lister);
© www.soinside.com 2019 - 2024. All rights reserved.