通过引用传递:多个接口的子级 [英] Passing by reference: child of multiple interfaces

查看:112
本文介绍了通过引用传递:多个接口的子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将实现多个接口的对象传递给仅需要其中一个接口的函数时,出现构建错误.

I'm getting build errors when passing an object that implements multiple interface to a function that requires only one of the interfaces.

我正在开发一个通讯包. 该程序包具有一个接收器类和一个发送器类. Receiver类使用通知接口Receive_Notifier(函数对象)来处理通知.同样,Sender类使用通知接口Send_Notifier来处理通知.

I'm developing a communication package. The package has a Receiver class and a Sender Class. The Receiver class uses a notification interface Receive_Notifier (function object) for handling notifications. Likewise the Sender class uses a notification interface Send_Notifier to handling notifications.

interface Send_Notifier
{
    void sending_text(string text);
}

interface Receive_Notifier
{
    void raw_text_received(string raw_text);
}

class Sender
{
    Send_Notifier m_notifier = null;
    public Sender(ref Send_Notifier notifier)
    {
        m_notifier = notifier;
    }
    public void send(string text)
    {
        m_notifier.sending_text(text);
        return;
    }
}

class Receiver
{
    Receive_Notifier m_notifier = null;
    public Sender(ref Receive_Notifier notifier)
    {
        m_notifier = notifier;
    }
    public void receive(string text)
    {
        m_notifier.raw_text_received(text);
        return;
    }
}

我已经将接口组合成一个Communications_Notifier:

I have combined the interfaces into a Communications_Notifier:

interface Communications_Notifier
    : Send_Notifier, Receive_Notifier
{
}

我创建了一个实现Communications_Notifier接口的Notifier类:

I created a Notifier class that implements the Communications_Notifier interface:

class Notifier
    : Communications_Notifier
{
    public void sending_text(string text)
    {
        System.Console.WriteLine("--> " + text);
    }
    public void raw_text_received(string raw_text)
    {
        System.Console.WriteLine("<-- " + raw_text);
    }
}

为简化本文,我仅显示发送者类:

To simplify this post, I'll only show the sender class:

class Sender
{
    Send_Notifier m_notifier = null;
    public Sender(ref Send_Notifier notifier)
    {
        m_notifier = notifier;
    }
    public void send(string text)
    {
        m_notifier.sending_text(text);
        return;
    }
}

问题是当我将Notifier的实例传递给Sender类的实例时:

The issue is when I pass an instance of the Notifier to an instance of the Sender class:

class Program
{
    static void Main(string[] args)
    {
        Notifier the_notifier = new Notifier();
        Sender talker = new Sender(ref the_notifier); // ** Error generating line

        talker.send("Hello\n");

        string pause_text;
        pause_text = System.Console.ReadLine();
    }
}

Visual C#Express 2010中的错误:

The errors from Visual C# Express 2010:

Error   1   The best overloaded method match for 'Multiple_Inheritance_Interface.Sender.Sender(ref Multiple_Inheritance_Interface.Send_Notifier)' has some invalid arguments    C:\Users\Thomas\Programming_Experiments\C_Sharp\Multiple_Inheritance_Interface\Multiple_Inheritance_Interface\Program.cs    55  29  Multiple_Inheritance_Interface  
Error   2   Argument '1': cannot convert from 'ref Multiple_Inheritance_Interface.Notifier' to 'ref Multiple_Inheritance_Interface.Send_Notifier'   C:\Users\Thomas\Programming_Experiments\C_Sharp\Multiple_Inheritance_Interface\Multiple_Inheritance_Interface\Program.cs    55  44  Multiple_Inheritance_Interface

问题:

  1. 为什么Notifier不能 转换为类型的引用 Sender,因为它实现了 Sender界面?
  2. 为什么是 构造函数无效吗?
  1. Why can't the Notifier be converted to a reference of type Sender, since it implements the Sender interface?
  2. Why is the argument to the constructor invalid?

注意:我正在从C ++,C和Java背景过渡到C#.

推荐答案

ref参数不支持协方差或相反方差.这是必需的,因为它既可以读取也可以更改参考.因此,如果您传入一个派生类,并且该函数分配了一个非该派生类型的新实例,则代码将中断.

ref parameters support no co- or contra-variance. This is necessary since it can both read and change the reference. So if you passed in a derived class, and the function assigned a new instance that's not of that derived type your code would break.

示例:

void MakeCat(ref Animal animal)
{
  animal=new Cat();
}

Dog dog=new Dog();
MakeCat(ref dog);

这显然是行不通的,因为现在您在dog变量中有了一个Cat.

This obviously can't work since now you'd have a Cat in your dog variable.

我不确定为什么首先要使用ref.使用引用类型,您已经可以更改传入的实例的内容.您不能用传入的引用类型的新实例替换传入的变量.

I'm not sure why you're using ref in the first place. With reference types you already can change the content of the instance passed in. You just can't replace the variable passed in with a new instance of that reference type.

out参数看起来像它们可能是协变的.我怀疑它们不是由于运行时的限制引起的:它们实际上是标记为属性的ref参数,告诉编译器将其视为out参数.

out parameters on the other hand look like they could be covariant. I suspect that they aren't is due to a limitation in the runtime: They are really ref parameters marked with an attribute telling the compiler to treat it as an out parameter.

这篇关于通过引用传递:多个接口的子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆