[英]Getting inconsistent accessibility error while trying to have protected constructor in base abstract class with interface injected marked as internal
我有 1 个接口 IMetadata,我想限制对当前程序集(类库)的访问,而不是在它之外,因此我将其标记为内部。
现在我想把这个接口注入到我的基抽象类中,并在我的基类方法上调用 IMetadata 的方法来执行一些逻辑。 例如,基类将从派生类 Type1 接收版本控制,因此我已将基抽象类构造函数标记为受保护,但出现以下错误:
不一致的可访问性:参数类型 IMetadata 的可访问性低于 BaseType.BaseType(IMetadata)
但是这个元数据总是会从派生类(Type1)接收它的具体类型,因此我希望这个基类构造函数受到保护,并且我希望元数据只在当前程序集中可用,而不是在它之外。
internal interface IMetadata
{
string CreateMetadata();
}
internal class Metadata : IMetadata
{
public Metadata(string location)
{
this.location = location;
}
public string CreateMetadata()
{
}
}
public interface IBaseType
{
Void Perform();
}
public abstract class BaseType : IBaseType
{
private readonly IMetadata _metadata;
protected BaseType(IMetadata metadata) //error
{
}
}
class Type1 : BaseType
{
public Type1(IMetadata metadata) :
base(metadata)
{
}
}
谁能告诉我问题是什么以及如何实现这种封装?
编译器执行这些可访问性检查的原因是试图引导您进入“成功之坑” 。 您将“东西”标记为(或允许默认)为internal
。 这意味着它是程序集中的一个实现细节。 程序集之外的任何东西都不应该知道或关心这个“东西”是什么。 它当然无法“说出它的名字”或创建一个。
然后你写一些public
或protected
。 这些东西是给其他组件可见。 然后你说“为了使用它,你必须提供一个东西”。 你泄露了一个实现细节,这就是编译器阻止你的原因。 您需要仔细研究这一点,并决定它不是纯粹的实现细节(因此将其public
),或者您不应该将它暴露在程序集之外。
理想情况下,您将此构造函数标记为带有正确语义的private protected
- 只有{从此类继承的类}和{此程序集中的类}的交集才能调用它。 无论如何,只有程序集的其他成员才能获得所需的实例。
但是,如果您还没有使用 C#7.2,则必须做出选择。 我会选择internal
。 无论如何,它是一个抽象类,即使使用理论上与继承层次结构无关的构造函数,也没有人可以直接构造它。
这编译得很好并显示了两种方法:
internal interface IMetadata
{
string CreateMetadata();
}
internal class Metadata : IMetadata
{
private readonly string location;
public Metadata(string location)
{
this.location = location;
}
public string CreateMetadata()
{
return string.Empty;
}
}
public interface IBaseType
{
void Perform();
}
public abstract class BaseType : IBaseType
{
private readonly IMetadata _metadata;
private protected BaseType(IMetadata metadata) //No error
{
}
internal BaseType(IMetadata metadata, int thing) //No error
{
}
public abstract void Perform();
}
class Type1 : BaseType
{
public Type1(IMetadata metadata) :
base(metadata)
{
}
public Type1(IMetadata metadata, int thing) : base(metadata, thing)
{
}
public override void Perform()
{
throw new NotImplementedException();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.