覆盖但不调用
如何在 C# 中声明一个应该由派生类重写(或可重写)的方法(甚至可能在程序集外部),但只能从实际类中调用?
(即像 C++ 中的私有虚函数)
[编辑]private
virtual
正是我的意图:“这里有一种方法可以修改我的行为,但仍然不允许您直接调用此函数(因为调用它需要神秘的调用,只有我的基类才能执行)”
因此澄清一下:C# 中最好的表达方式是什么?
How do you declare a method in C# that should be overridden (or overridable) by a dereived class - possibly even outside your assembly - but that should be callable only from within the actual class?
(i.e. like a private virtual function in C++)
[edit]private
virtual
is exactly what I intend: "Here's a way to modify my behavior, but you are still not allowed to call this function directly (because calling it requires arcane invocations that only my base class shall do)"
So to clarify it: what is the best expression for that in C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
当您说它只能在“实际类内”调用时,您是指基类还是派生类? 这些本身都不可行。 最接近的是使用受保护的方法,这意味着可以从声明类、派生类和任何进一步派生类调用它。
When you say it should only be callable "within the actual class" do you mean the base class or the derived class? Neither of these is feasible on its own. The closest is to use a protected method, which means it can be called from the declaring class, the derived class, and any further-derived class.
C# 对“私有”的保证比 C++ 更强。 在 C++ 中,您确实可以重写私有虚拟方法。 但这意味着基类中的代码可以执行派生类中的代码。 打破了私有方法是真正私有的并且只能被同一个类中的方法调用的承诺。
这里没有帮助的是 C++ 不需要重复 virtual 关键字。 导致像这样的难以逆向工程的谜团:
我同意私有继承可能发挥作用。 C# 语言设计者说不! 尽管。
C# makes a stronger guarantee for "private" than C++ does. In C++, you can indeed override a private virtual method. But that means that code in a base class can execute code in a derived class. Breaking the promise that the private method is truly private and can only be called by methods in the same class.
Something that doesn't help here is that C++ doesn't require repeating the virtual keyword. Leading up to hard to reverse-engineer mysteries like this one:
I agree there's a possible role for private inheritance. The C# language designers said No! though.
私有成员对子类不可见。 我认为受保护的虚拟会按照您想要的方式执行?
更新:
这里更详细地解释了您可以在 C# 中使用继承和重写函数做什么。 我尝试使用一个有点有意义的示例,但认为它是一个糟糕的类设计,我永远不会建议实现以这种方式描述的类。 然而,我希望这或许能为您提供一种以可接受的方式解决原始问题的途径。 没有办法阻止具体类调用其任何成员,但如果您的结构无论如何都是这样,也许这不是问题。
在这个例子中,Bird、Zebra 和 Fish 都可以调用它们的 Name 和 Legs 方法,但是在这个例子的上下文中,这样做不一定有用。 此外,如 Fish 所示,可以针对具体派生类的实例修改 DisplayAttributes(); 但是当您查看动物时,如在 foreach 循环中一样,您将获得基类 DisplayAttributes 行为,而不管动物的实际类型如何。 我希望这可以帮助提供您想要复制的功能类型。
A private member is not visible to child classes. I think protected virtual will perform the way you'd like?
UPDATE:
Here in greater detail is an explaination of what you can do with inheritance and overriding functions within C#. I tried to use a somewhat meaningful example, but consider it understood that its a poor class design and I wouldn't ever recommend implementing the classes described in this way. However, I hope perhaps this will give you an avenue to approach solving your original problem in a manner that might be acceptable. There is no way to prevent a concrete class from calling any of its members, but if your structure is like this in anyway, perhaps its not issue.
In this example, Bird, Zebra, and Fish could all call their Name and Legs methods, but within the context if this example, there wouldn't necessarily be utility in doing so. Additionally, as shown by Fish, the DisplayAttributes() can be modified for an instance of a concrete derived class; but when you're looking at an Animal, as in the foreach loop, you get the base classes DisplayAttributes behavior, regardless of the actual type of animal. I hope this may help povide the type of functionality you would like to replicate.
这是 vboctor 已经提到过的示例:
Here's an example of what vboctor has already mentioned:
您是否考虑过使用代表来做到这一点? 您可以允许派生类通过某些受保护的属性设置委托或将其传递给构造函数。 您还可以将委托默认为内部实现,这是基类上的私有方法。
Did you consider the use of a delegate to do that? You can allow the derived class to set the delegate via some protected property or passing it to your constructor. You can also default the delegate to your internal implementation which is a private method on your base class.
为什么需要将其设为私有? 在这里,受保护应该足够了。 您要求子类作者编写他们无法调用的代码。 这能达到什么目的呢? 无论如何,他们可以使用该代码。
Why do you need it to be private? Protected should be sufficient, here. You're asking the subclass author to write code that they can't call. What does this accomplish? They could use that code anyway.
当我读到你的问题时,你可能意味着两件事。
首先,如果您想要 A 类中的一个函数可以在子类 B 中重写,但对任何外部类都不可见:
其次,如果您想强制实现类定义该函数:
您可能会考虑另一个概念,如果您正在深入研究与部分类相关的 C#。 这是在编译时组合两个源文件以创建一个类的想法,两个源文件都来自同一个程序集:
文件 1:
文件 2:
部分文件不被广泛使用,除非处理设计生成的文件(例如 Linq2Sql 文件)或EDM 或 WinForms 等
As I read your question, you could mean two things.
First ,if if you want a function in Class A that can be overriden in Child Class B but is not visible to any outside class:
Second, if you want to force an implementing class to define the function:
Another concept you might look at if you are just digging into C# that is kinda related is partial classes. This is the idea of two source files being combined at compile time to create one class, both from the same assembly:
File 1:
File 2:
Partials are not widely used except when dealing with designed-generated files, like the Linq2Sql files, or EDM, or WinForms, etc.
我猜这不会按您的预期进行,但让我为您画一些伪代码:
Guess this will not work out as you intended, but let me sketch some pseudo-code for you: