gpt4 book ai didi

c#:在两个不同的上下文中重用部分类定义

转载 作者:行者123 更新时间:2023-12-04 16:53:26 25 4
gpt4 key购买 nike

我正在尝试重新使用公共(public)部分类定义来定义几个不同的类。这是说明所需结果的概念性(非工作)代码:

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”)。目前我使用自动生成器脚本复制公共(public)块,但想知道 在 c# 中是否有更优雅的方法来做到这一点?

澄清一下 - 上面的代码只是一个说明,我理解为什么它不起作用(不能跨命名空间拆分部分类定义)。此外,虽然在上面的示例中,我可以只拥有一个基本公共(public)类,但实际上它确实需要是同一个类,我通过部分定义实现了这一点。

--- 稍后添加 ---

好的,在阅读了答案后,我意识到我的问题的答案是“否”,我感谢你们证实了我的恐惧,即使用部分类没有简单的出路。让我试着详细说明我是如何提出这个问题的。也许你会给我指出一些简单而优雅的解决方案。想象一下,有一个巨大的类描述了一些硬件模型以及模拟它的方法,它是根据一些硬件描述自动生成的。就像是:
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(或其他任何东西)。部分钩子(Hook)方法和调用得到优化,每个人都很高兴。现在,我希望能够在自动生成的文件之外轻松定义钩子(Hook),并且我需要钩子(Hook)能够访问它们各自的所有类字段和方法。每次我想使用其中一个钩子(Hook)时,为钩子(Hook)所需的数据定义一个特殊的接口(interface)是不可能的。假设我想在 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()

现在,这就是我想要做的:能够使用 修改所有十个 CPUx 类的行为同 Hook 代码(假设 CPU1..10 结构足够相似以允许这样做)。我会用#include 语句实现的东西,或者如果部分类允许某些语法将相同的代码拉入多个类(例如在那个概念性的非工作示例中,它回避了“为什么要”这个问题),或者我现在做什么一个从字面上复制 10 个类的钩子(Hook)代码的脚本。

这对 c# 来说太脏了吗?

最佳答案

我怀疑您是从更多的 C/C++ 思维方式而不是 C# 思维方式来解决这个问题的。在早期的语言中,您可以通过 #include 以您想要的方式重用源代码,但 C# 更倾向于重用已编译的程序集而不是重用原始源代码。

除了从公共(public)基类继承之外,向现有类 (AFAIK) 添加功能的唯一方法是使用扩展方法:

namespace context1
{
public class A
{
internal String s = "context1";
}
}

namespace context2
{
public class A
{
internal String s = "context2";
}
}

namespace common
{
public static class ExtensionsForA
{
public static void f(this context1.A a) { common_f(a.s); }
public static void f(this context2.A a) { common_f(a.s); }

private static void common_f(string s) { Console.WriteLine(s); }
}

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();
}
}
}

不幸的是,这种方法有其自身的问题,例如确保扩展方法可以访问所有必要的成员,并且必须为每个上下文维护一个合适的 f() 版本,所以我不一定推荐它。

或许如果您给我们更具体地描述您的问题,我们或许能够为您提供更优雅的解决方案。

关于c#:在两个不同的上下文中重用部分类定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26198417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com