抽象类中的内部抽象方法有什么用途? 为什么会将抽象方法设置为抽象类的内部方法?如果我们想要将抽象类限制在程序集内部,为什么不直接将其声明为内部抽象类呢?可能还有其他的逻辑原因。
抽象类中的内部抽象方法有什么用途? 为什么会将抽象方法设置为抽象类的内部方法?如果我们想要将抽象类限制在程序集内部,为什么不直接将其声明为内部抽象类呢?可能还有其他的逻辑原因。
在一个public
的抽象类中添加internal
成员会使得这个抽象类无法在声明它的程序集之外继承。但是该抽象类本身以及所有派生类仍然可以在声明程序集之外被使用(因为类型是public
的)。
假设你有一个抽象类:
public abstract AMyClass
{
public string DoSomething()
{
return DoSomethingInternal();
}
internal abstract string DoSomethingInternal();
}
还有另一个公共类继承它,在同一程序集中声明。
public sealed MyClass : AMyClass
{
internal override string DoSomethingInternal()
{
return "Hey from MyClass!";
}
}
您仍然可以在不同的程序集中创建MyClass
实例,但是您将无法实现派生自AMyClass
的自定义类,因为您将无法实现抽象的DoSomethingInternal
方法。
internal关键字是类型和类型成员的访问修饰符。 内部类型或成员仅在同一程序集中的文件中可访问,例如:
public class BaseClass
{
// Only accessible within the same assembly
internal static int x = 0;
}
public abstract BaseClass
{
internal abstract void Print();
}
public abstract BaseClass
{
internal abstract void Print();
public abstract void Hello();
}
在BaseClass程序集之外的类将无法使用此类,因为其中一个成员是internal。 解决方案是在与BaseClass相同程序集中创建子类,并将该类用于程序集外部。
我建议您从@john skeet的《深入C#》中阅读有关C#访问修饰符概念的内容。
想象一下你的项目中有一段代码
假设它是一个控制台应用程序,我们称之为ConsoleApplication1
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{}
}
public abstract class MyAbsClass
{
public string DoSomething()
{
return DoSomethingInternal();
}
internal abstract string DoSomethingInternal();
public abstract string DoSomethingExternal();
}
public class MyClass:MyAbsClass
{
internal override string DoSomethingInternal(){}
public override string DoSomethingExternal(){}
}
}
现在假设您有另一个控制台应用程序(称为ConsoleApplication2),您需要构建您的ConsoleApplication1并添加对其的引用。
using ConsoleApplication1;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
}
}
class NewClass : MyAbsClass
{
public override string DoSomethingExternal()
{
throw new NotImplementedException();
}
}
}
Error 1 'ConsoleApplication2.NewClass' does not implement inherited abstract member 'ConsoleApplication1.MyAbsClass.DoSomethingInternal()
为什么会出现这个错误?因为编译器告诉你,当你将成员声明为internal时,与其在同一程序集中的类(即ConsoleApplication1)可以访问它。所以无论你在ConsoleApplication2中创建多少个类,你都无法访问它,因为它被声明为internal。
public abstract class ServerProtocol
(System.Web.Services.Protocols.ServerProtocol
),并且该类具有internal abstract
成员,但是在VS2019中编译正常,并且ILSpy显示它存在。但是当我尝试在LinqPad 5中实例化它时,我只会得到一个运行时的TypeLoadException
。而旧版本的VS确实会阻止编译。这很奇怪... - Dai