2013-07-02 46 views
3

考虑代码:从Base继承,迫使他们无论从AB继承是否有可能阻止一个抽象类的继承

public abstract class Base 
{ 
    public Dictionary<int, string> Entities { get; private set; } 

    protected Base() 
    { 
     Entities = new Dictionary<int, string>(); 
    } 
} 

public abstract class A : Base 
{ 
    public abstract void Update(); 
} 

public abstract class B : Base 
{ 
    public abstract void Draw(); 
} 

是否有可能限制类(在相同的程序集) ?

+7

否那么'A'和'B'会如何继承? –

+0

你的意思是,你想让A和B继承Base,但没有其他类? – crush

+0

@crush是的,正是这样。这并不重要,但我很想知道这是否可能。 – Steve

回答

3

对我的评论进行一点说明。这不被支持,所以答案是否定的。想到这种想法的唯一办法就是设置一个sealed abstract类,这是荒谬的,因为AB或其他任何东西都不能继承。

例如,没有鉴别符可以让我们说“被密封”。

+0

非常感谢,并且当你的评论是第一次,我会接受你的答案,谢谢。 – Steve

2

防止继承的唯一方法是声明类像密封。

public sealed abstract class A 
{ 
} 

,但你会得到编译错误:

Abstract class can not be declared sealed.

这样做的原因是,根本没有在decalring抽象类和限制了其继承树任何意义。 Abstact分类一个实体,它的目标是根据其定义进行扩展。

+0

我对密封进行了实验,并获得了您所描述和预期的错误。感谢您的洞察力。 – Steve

1

你可以做,据我所知道的最接近的事,是这样的:

public abstract class Base 
{ 
    internal Base() 
    { 
     // do stuff 
    } 
} 

然后移动ABBase到自己组装。组件外的任何东西都可以看到Base,但无法直接扩展它,因为它无法访问构造函数。

或者你可以做一个运行时检查:

public abstract class Base 
{ 
    protected Base() 
    { 
     if (!(this is A || this is B)) 
     // throw an exception 
    } 
} 
+0

感谢您的其他选择。 – Steve

+0

第二种选择看起来不像是一种很好的编码方式。虽然适合于手头的任务。 – zaitsman

+0

@zaitsman我同意。我可能应该包括关于做这种事有多糟糕的声明。 –

0

轮的唯一途径,我能想到的办法是有这样的:

A.DLL

internal abstract class Base 
{ 
    public Dictionary<int, string> Entities { get; private set; } 

    protected Base() 
    { 
     Entities = new Dictionary<int, string>(); 
    } 
} 

B.dll

public abstract class A : Base 
{ 
    public abstract void Update(); 
} 

public abstract class B : Base 
{ 
    public abstract void Draw(); 
} 

C.dll

public class C : A 
{ 
    public void Draw() 
    { 
    } 
} 

,然后使用[组件:InternalsVisibleTo ...]在A.DLL的AssemblyInfo.cs中,使内部类可见B.ll.免责声明:这是相当复杂的,我不会推荐它,但我想不出任何方式来满足你的约束。