C#在类之间共享代码

在使用C#的Visual Studio 2008中,跨多个类和源文件共享代码的最佳方法是什么?

inheritance不是解决方案,因为类已经具有有意义的层次结构。

是否有一些简洁的function,就像一个C包含文件,让你在其他类中的任何地方插入代码?

编辑:

好吧,我想我们需要一个具体的例子……

该领域有数百个类,经过深思熟虑的类heirarchy。 现在,许多这些类需要打印。 有一个实用程序打印机类来处理打印。 假设有3种不同的打印方法依赖于正在打印的类。 调用print方法的代码(6行)是我试图避免在所有不同的客户端类页面上复制和粘贴的代码。

如果人们不会认为他们对操作领域有更多了解,那会很好 – 特别是当他们特别提到不合适的技术时……

如果您在代表非常不同的事物的类中经常使用的function,根据我的经验,应该只分为几类:

  • 实用程序(例如字符串格式化,解析,……)
  • 跨领域的问题(日志记录,安全执法……)

对于实用程序类型的function,您应该考虑创建单独的类,并引用业务类中所需的实用程序类。

public class Validator { public bool IsValidName(string name); } class Patient { private Validator validator = new Validator(); public string FirstName { set { if (validator.IsValidName(value)) ... else ... } } } 

对于日志记录或安全性等跨领域问题,我建议您研究面向方面编程 。

关于其他评论中讨论的PrintA与PrintB示例,它听起来像是工厂模式的一个很好的例子。 您可以定义一个接口,例如IPrint,类PrintA和PrintB,它们都实现IPrint,并根据特定页面的需要分配IPrint实例。

 // Simplified example to explain: public interface IPrint { public void Print(string); } public class PrintA : IPrint { public void Print(string input) { ... format as desired for A ... } } public class PrintB : IPrint { public void Print(string input) { ... format as desired for B ... } } class MyPage { IPrint printer; public class MyPage(bool usePrintA) { if (usePrintA) printer = new PrintA(); else printer = new PrintB(); } public PrintThePage() { printer.Print(thePageText); } } 

您不能像在C中那样通过预处理器指令加载您希望添加到C#类中的代码。

但是,您可以定义接口并为该接口声明扩展方法。 然后可以通过类实现接口,并且可以在这些类上调用扩展方法。 例如

 public interface IShareFunctionality { } public static class Extensions { public static bool DoSomething(this IShareFunctionality input) { return input == null; } } public class MyClass : Object, IShareFunctionality { public void SomeMethod() { if(this.DoSomething()) throw new Exception("Impossible!"); } } 

这将允许您重用function,但是如果您可以,例如,哈希包含文件,则无法访问类的私有成员。

我们可能需要一些更具体的例子来说明你想做什么?

AC#实用程序类将起作用。 它就像公共代码的中央注册表(或者像VB.NET模块构造一样) – 它应该包含不特定于任何类的代码,否则它应该附加到相关类。

如果不需要,希望开始复制源代码,因为考虑到重复 ,这会导致代码更新问题。

只要源不需要保留状态,则使用静态类和静态方法。

 static public class MySharedMembers { static public string ConvertToInvariantCase(string str) { //...logic } // .... other members } 

如果类在同一名称空间中,则不需要包含模拟。 只需调用另一个函数中定义的类的成员即可。

如果它们不在同一名称空间中,请在usings指令中添加要使用的类的名称空间,它应该与上面相同。

我对这个问题感到困惑:似乎你需要在你的基本OO理解上工作。

结帐扩展方法: http : //msdn.microsoft.com/en-us/library/bb383977.aspx

我不知道包含部分文件的方法,但我们经常做的一件事是添加现有文件并从当前位置“链接”它。 例如,我们有一个assemblyInfo.cs文件,每个项目都是从一个解决方案目录引用的。 我们更改它一次,所有项目都有相同的信息,因为它们指的是同一个文件。

否则,关于在common.dll中重构“常见”例程的建议是我在.Net中提出的最好的事情。

我不确定你的“有意义”结构究竟是什么意思,但这听起来像是一个可以使用基类实现的地方。 虽然不像C ++多重inheritance那样“冗长”,但是使用链式基类实现来重用常用函数可能会带来一些好处。

您可以保留类层次结构,至少可视化并根据需要覆盖行为。

将重复代码拉出到服务中。 重复代码是一个线索,可能有一些重构的空间。

例如,创建一个“PrintingService”,其中包含打印所需的逻辑。 然后,您可以让需要打印的类依赖于此服务(通过构造函数或需要服务的方法中的参数)。

我在这些方面的另一个技巧是为基本function创建接口,然后使用接口进行编码。 例如,我有一堆报告类,用户可以通过传真,电子邮件或打印。 我没有为每个创建方法,而是为每个创建了一个服务,让他们实现一个具有Output()方法的接口。 然后,我可以根据用户想要的输出类型将每个服务传递给相同的方法。 当客户想要使用eFax而不是通过调制解调器传真时,只需编写实现此相同界面的新服务即可。

说实话,我想不出像Visual C#中包含的东西,也不会想到为什么你会想要这个function。 也就是说,部分类可以做类似于你想要的事情,但使用它们可能会对你的“类已经有一个有意义的层次结构”要求发生冲突。

你有很多选择,TT,扩展方法,委托和lambda