C# 可互换使用轻型和全尺寸物体的设计
我在一个系统中工作,该系统使用的接口和类结构与此类似:C# 可互换使用轻型和全尺寸物体的设计,c#,inheritance,dry,C#,Inheritance,Dry,我在一个系统中工作,该系统使用的接口和类结构与此类似: interface ILw // a lightweight interface definition class Medium : ILw class FullA : Medium // full class definitions class FullB : Medium class LwA : ILw // lightweight class definit
interface ILw // a lightweight interface definition
class Medium : ILw
class FullA : Medium // full class definitions
class FullB : Medium
class LwA : ILw // lightweight class definitions
class LwB : ILw
在系统中,我遇到的对象可能是完整的或轻量级的,因此具有预期ILw接口的功能。我在这种设计中遇到的问题是,与ILw中定义的相比,需要在对象的完整版本和轻量级版本之间共享的数据和方法更多。所以我发现自己需要做这样的事情:
if (myvar is FullA)
{
(myvar as FullA).MyFunction()
}
else
{
(myvar as LwA).MyFunction()
}
其中MyFunction()在每个FullA和LwA中分别实现,并且可以在相同的数据结构上工作。我想消除这种代码重复
用C++背景,它似乎是多重继承的典型案例;i、 例如,为需要的数据和方法定义一个类SharedA,并将其添加到FullA和LwA的父列表中。但我需要一些指导来帮助在C#和接口世界中思考这一点。有没有公认的模式来解决这个问题
多谢各位 更新: 在迄今为止收到的评论的帮助下,我已经能够通过1)一个中间接口(需要共享数据的聚合)和2)一个扩展类(用于处理此数据的方法)进行重构以获得更好的设计。理想情况下,这些(数据和方法)将连接在同一个结构中。我觉得mate-in-1在董事会上,我只是看不到public interface ILwBase { }
class Medium : ILwBase { }
public class LwDataA
{
static private int _count = 0;
public int id;
public LwDataA() { id = ++_count; }
}
public interface ILwA : ILwBase
{
LwDataA ExtData { get; }
}
public static class ExtLwA
{
public static void MyFunction(this ILwA o)
{
Console.WriteLine("id = " + o.ExtData.id);
}
}
class LwA : ILwA
{
private LwDataA _extData = new LwDataA();
public LwDataA ExtData { get { return (_extData); } }
}
class FullA : Medium, ILwA
{
private LwDataA _extData = new LwDataA();
public LwDataA ExtData { get { return (_extData); } }
}
class Program
{
static void Main()
{
ILwA a1 = new FullA();
ILwA a2 = new LwA();
a1.MyFunction();
a2.MyFunction();
}
}
这使得我只需要在LwA和FullA之间使用两行重复代码就可以实现所需的功能。它还消除了通过聚合属性(我以前的编辑)调用或围绕聚合实现包装器的需要
希望这能澄清我想要实现的目标。这是最好的解决方案吗?在我们的评论交流之后,您的问题现在被从不同于原始帖子的角度看待。你不能直接拥有多重继承给你的东西。但是有很多方法可以让你非常接近 变量1:欺骗需要
MyFunction()
的特殊类,将其作为扩展方法接收。要做到这一点,你需要“与众不同”;在我的示例中,这就是ILwA接口。请注意,它必须定义另一个通用性,而不是MyFunction()
。一个能手(或二传手)就行了。这里的限制是MyFunction不能访问私有成员
//instead of the lightweight interface (but use interface if it makes more sense)
abstract class LwBase
abstract class HwBase : LwBase
public interface IADiff { int APropTrick { get; } }
// lightweight class definitions
class LwA : LwBase, IADiff
class LwB : LwBase
// full class definitions
class FullA : HwBase, IADiff
class FullB : HwBase
public static class AExtensions
{
public static void MyFunction(this IADiff o)
{
// impl.
}
}
变量2:使用一个提供MyFunction()
实现并“重定向”到它的公共类:
变体3:我在研究你的问题时偶然发现了。我不能很快地说这是否是一个可行的选择,但它确实提供了一些想法
信用证:我大量借用了你的观点,并将其作为参考。在我们的评论交流之后,你的问题现在被从一个不同于原来文章的角度看待。你不能直接拥有多重继承给你的东西。但是有很多方法可以让你非常接近 变量1:欺骗需要
MyFunction()
的特殊类,将其作为扩展方法接收。要做到这一点,你需要“与众不同”;在我的示例中,这就是ILwA接口。请注意,它必须定义另一个通用性,而不是MyFunction()
。一个能手(或二传手)就行了。这里的限制是MyFunction不能访问私有成员
//instead of the lightweight interface (but use interface if it makes more sense)
abstract class LwBase
abstract class HwBase : LwBase
public interface IADiff { int APropTrick { get; } }
// lightweight class definitions
class LwA : LwBase, IADiff
class LwB : LwBase
// full class definitions
class FullA : HwBase, IADiff
class FullB : HwBase
public static class AExtensions
{
public static void MyFunction(this IADiff o)
{
// impl.
}
}
变量2:使用一个提供MyFunction()
实现并“重定向”到它的公共类:
变体3:我在研究你的问题时偶然发现了。我不能很快地说这是否是一个可行的选择,但它确实提供了一些想法
信用证:我大量借用了,也用作参考。要共享实现,您可以让它们都继承自
摘要
:
interface ILwBase // a lightweight interface definition
interface ILwA : ILwBase
interface ILwB : ILwBase
class Intermediate : ILwBase
abstract class AbstractA : ILwA {
void MyFunction() {...}
}
class LwA : AbstractA, Intermediate
class LwB : Intermediate
class FullA : AbstractA
class FullB : ILwB
阅读有关的更多信息要共享实现,您可以让它们都继承自
摘要
:
interface ILwBase // a lightweight interface definition
interface ILwA : ILwBase
interface ILwB : ILwBase
class Intermediate : ILwBase
abstract class AbstractA : ILwA {
void MyFunction() {...}
}
class LwA : AbstractA, Intermediate
class LwB : Intermediate
class FullA : AbstractA
class FullB : ILwB
阅读更多关于的信息,如果您需要以不同的方式对待FullA和LwA,它们真的可以说是编码到同一个界面上吗?也许你的界面被设计破坏了,需要做得更好/更全面?@Patashu很多时候我都不在乎我是否在处理一个“完整”的对象。在这些情况下,我需要能够处理的是两者之间常见的一小部分数据和方法。如果接口不能为您做到这一点(定义两者之间常见的所有方法),那么您的接口将被破坏。我不太理解您的问题。。。为什么接口中没有定义MyFunction()?让virtuals在Intermediate中就可以解决在子类中专门化“接口”的问题吗?MyFunction()没有在接口中定义,因为它只属于“A”类,而不属于“B”类。如果您需要以不同的方式对待FullA和LwA,它们真的可以说是编码到同一个接口吗?也许你的界面被设计破坏了,需要做得更好/更全面?@Patashu很多时候我都不在乎我是否在处理一个“完整”的对象。在这些情况下,我需要能够处理的是两者之间常见的一小部分数据和方法。如果接口不能为您做到这一点(定义两者之间常见的所有方法),那么您的接口将被破坏。我不太理解您的问题。。。为什么接口中没有定义MyFunction()?仅仅让virtuals在中间版本就可以解决在子类中专门化“接口”的问题吗?MyFunction()没有在接口中定义,因为它只属于“A”类,而不属于“B”类。抽象类解决了共享实现的问题。但是剩下的问题是使用中间类:
classlwa:AbstractA,Intermediate
不会编译,因为它是多重继承。哦,对不起,我认为Intermediate
也是一个接口。是我的错,是的,从我开始我很困惑。应该称之为中间类。一个抽象类