我发现自己需要这样的东西:
// This could just as well be a concrete class.
//
// It is an interface for the sake of this example.
public interface Quark
{
void Do();
}
public class Strange : Quark
{
public virtual void Do()
{
// Something is done
}
public void DoSpecificThing()
{
MessageBox.Show("Specific Thing!");
}
}
public class Charm : Quark
{
public virtual void Do()
{
// Something else is done
}
public void DoAnotherSpecificThing()
{
MessageBox.Show("Another Specific Thing!");
}
}
在另一个档案中:
internal class ReUsableCode<BaseType> : BaseType // <- not allowed
{
public override void Do()
{
// Let's pretend this is around 2000 lines of
// 90's-style Win32 message spaghetti.
MessageBox.Show(base.GetType().ToString() + " did!");
base.Do();
}
}
public class LibraryStrange : ReUsableCode<Strange>
{
}
public class LibraryCharm : ReUsableCode<Charm>
{
}
在某个地方的某个功能中:
LibraryStrange imStrange = new LibraryStrange();
LibraryCharm imCharmed = new LibraryCharm();
imStrange.Do();
imStrange.DoSpecificThing();
imCharmed.Do();
imCharmed.DoAnotherSpecificThing();
在C ++中,我只是制作一个完全符合上述要求的模板。
由于上述原因,这在C#中是不可能的,并且也不允许多重继承。那么,如果没有复制和粘贴,或者强制一切都从单个基类继承,如何重用词法上相同的实现呢?
这是为了减少所有用户控件库所需的维护工作,这些控件全部继承自System.Windows.Forms
中的内容,并以完全相同的方式覆盖WndProc
(代码全部被复制和粘贴,而我正试图消除或集中它。)
注意:我没有做大量的C#工作,所以请原谅我,如果这个问题看似基本或滥用这个领域的术语。
答案 0 :(得分:2)
您可以使用扩展方法进行排序。
public static class ExtensionMethods {
public static void Do(this ICommon obj, String someArg) {
Console.WriteLine( obj.GetType().Name + " foobar " + someArg );
}
}
public interface ICommon {} // interface doesn't do anything
public class Strange : ICommon {
}
public class Charm : ICommon {
}
public static class Program {
public static void Main(String[] args) {
Strange quark = new Strange();
Charm rom = new Charm();
quark.Do("blargh");
rom.Do("blargh");
}
}
答案 1 :(得分:2)
我提出的最简单的解决方案是放弃继承,转而使用合成。不幸的是,它需要概括“SpecificThing”概念。
问题恰恰在于SRP和ISP在您的设计中受到侵犯,而您提出的所有内容都只是为了避免问题而不是解决问题! / p>
你在评论中写下“基本类型”有问题[...] - 并且把它放在引号中是好的 - 这些不应该是基类型。然而,这个公式过于笼统,很难明确指出什么是错的 - 这里的一切似乎都是错误的。
public interface Quark
{
void Do();
}
public interface SpecificQuark : Quark
{
void DoSpecificThing();
}
public class Strange : SpecificQuark
{
public virtual void Do()
{
// Something is done
}
public void DoSpecificThing()
{
Console.WriteLine("Specific Thing!");
}
}
public class Charm : SpecificQuark
{
public virtual void Do()
{
// Something else is done
}
public void DoSpecificThing()
{
Console.WriteLine("Another Specific Thing!");
}
}
class ReUsableCode<T>
where T: SpecificQuark, new()
{
public T InnerQuark { get; private set; }
public ReUsableCode()
{
this.InnerQuark = new T();
}
public void Do()
{
// Let's pretend this is around 2000 lines of
// 90's-style Win32 message spaghetti.
Console.WriteLine(InnerQuark.GetType().ToString() + " did!");
this.InnerQuark.Do();
}
}
class LibraryStrange : ReUsableCode<Strange>
{
}
class LibraryCharm : ReUsableCode<Charm>
{
}
然后:
LibraryStrange ls = new LibraryStrange();
LibraryCharm lc = new LibraryCharm();
ls.Do();
ls.InnerQuark.DoSpecificThing();
lc.Do();
lc.InnerQuark.DoSpecificThing();