与接口相关的访问修饰符

Access modifiers related to interface

我对 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers

中的以下段落感到困惑

Normally, the accessibility of a member isn't greater than the accessibility of the type that contains it. However, a public member of an internal class might be accessible from outside the assembly if the member implements interface methods or overrides virtual methods that are defined in a public base class.

有谁能帮忙举个最后一句话的例子吗?如果 class 是内部的,则无法在程序集外部创建 class 的实例。怎么可能从程序集外部访问这样的 class 的成员,即使该成员被声明为 public?

谢谢

假设您创建了以下服务和接口:

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方法正在实现IFoovoid Bar();的接口需求。虽然消费者无法实例化 ConcreteFoo,但您的库中的其他实体可以创建和 return 一个 ConcreteFoo 装箱为 IFoo(即 public), 从而允许访问消费代码中的成员。

If the class is internal, then no instance of the class can be created outside the assembly.

实际上,class 可以使用反射在程序集外部创建。

更常见的是,class 可以在程序集内部创建,然后传递给程序集外部的方法,但只需转换为接口或父 class 即 [=38] =]可见。

例如,请考虑以下 C# 表达式:

((Expression<Func<int, bool>>) (i => i == 0))

此表达式的 Body 属性 被转换为 Expression,但该特定表达式的实际类型是 LogicalBinaryExpression,即 class 这是 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; }
        }
    }

请注意 public TypeNodeType 属性如何被此类型覆盖。因此,即使此类型是 internal 并且您永远不能在自己的代码中将其转换为 LogicalBinaryExpression,它仍然具有 public 成员,您可以通过 Expression 类型访问这些成员.

Console.WriteLine(((Expression<Func<int, bool>>) (i => i == 0)).Body.Type.ToString());
// Output: System.Boolean