【问题标题】:Access modifiers related to interface与接口相关的访问修饰符
【发布时间】:2021-03-14 00:34:48
【问题描述】:
我对@987654321@中的以下段落感到困惑
通常,成员的可访问性不大于包含它的类型的可访问性。但是,如果内部类的公共成员实现接口方法或覆盖公共基类中定义的虚拟方法,则该成员可能可以从程序集外部访问。
谁能帮忙举个最后一句话的例子?如果该类是内部的,则不能在程序集之外创建该类的任何实例。怎么可能从程序集外部访问此类的成员,即使该成员被声明为公共的?
谢谢
【问题讨论】:
标签:
c#
inheritance
interface
access-modifiers
【解决方案1】:
假设您创建了以下服务和接口:
public interface IFoo
{
void Bar();
}
internal class ConcreteFoo : IFoo
{
public void Bar()
{
Console.WriteLine("Hello from my concrete foo!");
}
}
然后你暴露一个工厂:
public class Factory
{
public IFoo CreateFoo()
{
return new ConcreteFoo();
}
}
Bar方法实现了IFoo中void Bar();的接口需求。虽然消费者无法实例化ConcreteFoo,但您的库中的其他实体可以创建并返回一个ConcreteFoo,并将其装箱为IFoo(这是公共的),从而允许访问消费代码中的成员。
【解决方案2】:
如果类是内部的,则不能在程序集之外创建该类的实例。
实际上,可以使用反射在程序集之外创建类。
更常见的是,可以在程序集内创建类,然后将其传递给程序集外的方法,但只需将其转换为公开可见的接口或父类。
例如,考虑以下 C# 表达式:
((Expression<Func<int, bool>>) (i => i == 0))
此表达式的 Body 属性被转换为 Expression,但该特定表达式的实际类型是 LogicalBinaryExpression,它是 System.Core 库的内部类。
internal sealed class LogicalBinaryExpression : BinaryExpression {
private readonly ExpressionType _nodeType;
internal LogicalBinaryExpression(ExpressionType nodeType, Expression left, Expression right)
: base(left, right) {
_nodeType = nodeType;
}
public sealed override Type Type {
get { return typeof(bool); }
}
public sealed override ExpressionType NodeType {
get { return _nodeType; }
}
}
请注意公共Type 和NodeType 属性如何被此类型覆盖。因此,即使这种类型是 internal 并且您永远无法在自己的代码中将其转换为 LogicalBinaryExpression,它仍然具有您可以通过 Expression 类型访问的公共成员。
Console.WriteLine(((Expression<Func<int, bool>>) (i => i == 0)).Body.Type.ToString());
// Output: System.Boolean