通过引用传递参数 - 继承和类型解析

时间:2013-08-02 23:29:16

标签: c# pass-by-reference

我遇到了通过引用传递对象的问题。假设我有一个名为ViewModelBase的对象,其定义如下:

public class ViewModelBase : IViewModelManager
{
    public ViewModelBase()
    {
    }

    // IViewModelManager implementation 
}

然后,我定义另一个来自ViewModelBase

的内容的对象
public class ExternalAssetViewModel : ViewModelBase
{
    public ExternalAssetViewModel()
    {
    }
}

然后我创建了一个名为NotificationHandler的静态类,它包含一个视图模型引用列表,因此一旦收到服务器通知,它就可以正确地更新视图模型:

public static class NotificationHandler
{
    private static List<ViewModelBase> viewModelReferences = new List<ViewModelBase>();

    public static void AddViewModelReference(ref ViewModelBase viewModel)
    {
        viewModelReferences.Add(viewModel);
    }
}

现在,每次创建需要更新的新视图模型时,我都会将其添加到此静态列表中:

ExternalAssetViewModel viewModel = new ExternalAssetViewModel();
NotificationHandler.AddViewModelReference(ref viewModel);

但是,这会因以下编译错误而失败:

Argument 1: cannot convert from 'ref ExternalAssetViewModel' to 'ref ViewModelBase'

即使ExternalAssetViewModel继承自ViewModelBase,但技术上ExternalAssetViewModel的类型为ViewModelBase。通过更改AddViewModelReference来获取泛型参数,然后为该参数定义约束,我能够解决这个问题:

public static void AddViewModelReference<T>(ref T viewModel) where T : ViewModelBase
{
    viewModelReferences.Add(viewModel);
}

现在编译器又开心了。所以我的问题是,为什么代码最初会破坏?为什么编译器无法实现被引用的对象与定义的参数类型相同?

1 个答案:

答案 0 :(得分:3)

您可能不需要ref

示例ref不允许您的代码的原因:

 void Method(ref MyBase v)
 {
      v = new MyBase();
 }

 MyDerived d = null;
 Method(ref d);

如果允许,会将MyBase分配给MyDerived,类似于以下明显错误的代码:

 MyDerived d = new MyBase();