【发布时间】:2014-10-05 00:16:23
【问题描述】:
我正在尝试重新使用常见的部分类定义来定义几个不同的类。这是说明所需结果的概念(非工作)代码:
namespace common {
// Here is the part of the class which I want to re-use
// literally in two different contexts
partial class A {
public void f() { Console.WriteLine(s); }
}
}
namespace context1 {
using common; // using as #include
partial class A {
String s = "contetx1";
}
}
namespace context2 {
using common; // using as #include
partial class A {
String s = "context2";
}
}
class Program {
static void Main(string[] args) {
context1.A a1 = new context1.A();
context2.A a2 = new context2.A();
a1.f();
a2.f();
Console.ReadKey();
}
}
context1 和 context2 中的代码是自动生成的。我想在自动生成的类中使用相同的手动编写代码(上面的命名空间'common')。目前我使用自动生成器脚本复制公共块,但想知道在 c# 中有更优雅的方法吗?
为了澄清 - 上面的代码只是一个说明,我理解它为什么不起作用(不能跨命名空间拆分部分类定义)。此外,虽然在上面的示例中我可以只拥有一个基本的公共类,但实际上它确实需要是同一个类,我通过部分定义来实现。
--- 稍后添加 ---
好的,在阅读了答案后,我意识到我的问题的答案是“否”,感谢你们确认我担心使用部分类没有简单的出路。让我尝试详细说明我是如何提出这个问题的。也许你会告诉我一些简单而优雅的解决方案。想象有一个巨大的类描述了一些硬件模型以及模拟它的方法,它是从一些硬件描述中自动生成的。比如:
partial class CPU1 : GenericCPU {
...
partial class register123 { /*...fields and methods...*/ }
...
partial class alu758 {
/*...thousand fields and methods with partial hook method definitions...*/
partial void start_get_data_hook();
partial void finish_get_data_hook();
void get_data() {
start_get_data_hook();
/*... some alu758-specific code for getting input data...*/
finish_get_data_hook();
}
...
}
...
void override simulate(); // Assume GenericCPU has virtual "simulate()"
}
假设没有其他任何东西,这模拟了一些 CPU(或其他)。部分钩子方法和调用得到优化,每个人都很高兴。现在,我希望能够轻松在自动生成的文件之外定义挂钩,并且我需要挂钩能够访问它们各自的所有类字段和方法。每次我想使用其中一个钩子时,为钩子所需的数据定义一个特殊接口是不可能的。假设我想在 CPU1.alu758.get_data() 的开头和结尾做一些特殊的事情,使用部分类和方法非常容易:
partial class CPU1 {
partial class alu758 {
/* some more fields which the hooks use */
partial void start_get_data_hook() { /* do some preparation stuff */ }
partial void finish_get_data_hook() { /* do some finalization stuff */ }
}
}
虽然只有一个 CPU1 类,但它可以完美运行。但是假设有 10 个自动生成的 CPU 类 CPU1..CPU10:
String processor_model = /* user input */;
GenericCPU cpu;
switch(processor_model) {
case "CPU1": cpu = new CPU1; break;
case "CPU2": cpu = new CPU2; break;
...
}
cpu.simulate()
现在,这就是我想要做的:能够使用 same 钩子代码修改所有十个 CPUx 类的行为(假设 CPU1..10 结构足够相似以允许那)。我会用#include 语句实现的东西,或者如果部分类允许某些语法将相同的代码提取到几个类中(例如在那个概念性的非工作示例中,它提出了“为什么在地球上”的问题),或者我现在用一个从字面上复制 10 个类的钩子代码的脚本。
这对 c# 来说太脏了吗?
【问题讨论】:
-
简短回答:不。长答案:为什么在地球上?
-
好的,在下面写完之后,刚刚看到你的更新。即使在不同的命名空间中,它们也不会是同一个类。这就是命名空间的全部意义所在。老实说,我以为我理解你的问题,但现在,不是那么多。
标签: c# namespaces partial-classes