在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
答案 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);