通过引用传递:多个接口的子接口
当将实现多个接口的对象传递给仅需要其中一个接口的函数时,我遇到构建错误。
我正在开发一个通讯包。 该包有一个 Receiver 类和一个 Sender 类。 Receiver 类使用通知接口 Receive_Notifier(函数对象)来处理通知。同样,Sender 类使用通知接口 Send_Notifier 来处理通知。
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 中:
interface Communications_Notifier
: Send_Notifier, Receive_Notifier
{
}
我创建了一个实现 Communications_Notifier
接口的 Notifier
类:
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);
}
}
为了简化这篇文章,我将仅显示发送者类:
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
类的实例时:
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 中的错误:
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
问题:
- 为什么
Notifier 不能
是 转换为类型的引用Sender
,因为它实现了发送者
接口? - 为什么争论是 构造函数无效?
注意:我正在从 C++、C 和 Java 背景过渡到 C#。
I'm getting build errors when passing an object that implements multiple interface to a function that requires only one of the interfaces.
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;
}
}
I have combined the interfaces into a Communications_Notifier:
interface Communications_Notifier
: Send_Notifier, Receive_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;
}
}
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();
}
}
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
Questions:
- Why can't the
Notifier
be
converted to a reference of typeSender
, since it implements theSender
interface? - Why is the argument to the
constructor invalid?
Note: I'm transitioning from a C++, C and Java background to C#.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ref
参数不支持协变或逆变。这是必要的,因为它既可以读取也可以更改引用。因此,如果您传入派生类,并且该函数分配了一个不属于该派生类型的新实例,您的代码将会中断。示例:
这显然行不通,因为现在您的
dog
变量中有一个Cat
。我不确定您为什么首先使用
ref
。使用引用类型,您已经可以更改传入实例的内容。您只是无法用该引用类型的新实例替换传入的变量。另一方面,
out
参数看起来可能是协变的。我怀疑它们不是由于运行时的限制而导致的:它们实际上是用属性标记的ref
参数,告诉编译器将其视为out
参数。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.Example:
This obviously can't work since now you'd have a
Cat
in yourdog
variable.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
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 reallyref
parameters marked with an attribute telling the compiler to treat it as anout
parameter.您误用了
ref
。在 C# 中,只有 struct 是传统意义上的“按值传递”。默认情况下,对象引用传递给方法。例如:因此,构造函数中根本不需要
ref
关键字。这与 Java 的行为类似,与 C 和 C++ 的行为不同。
You are misusing
ref
. In C#, onlystruct
s are "passed by value" in a traditional sense. By default, object references are passed to methods. For example:So there's no need at all for the
ref
keyword in your constructor.This is similar to Java's behavior, and dissimilar to C and C++'s behavior.