与接口相关的访问修饰符

Posted

技术标签:

【中文标题】与接口相关的访问修饰符【英文标题】:Access modifiers related to interface 【发布时间】:2021-03-14 00:34:48 【问题描述】:

我对@9​​87654321@中的以下段落感到困惑

通常,成员的可访问性不大于包含它的类型的可访问性。但是,如果内部类的公共成员实现接口方法或覆盖公共基类中定义的虚拟方法,则该成员可能可以从程序集外部访问。

谁能帮忙举个最后一句话的例子?如果该类是内部的,则不能在程序集之外创建该类的任何实例。怎么可能从程序集外部访问此类的成员,即使该成员被声明为公共的?

谢谢

【问题讨论】:

【参考方案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方法实现了IFoovoid 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; 
        
    

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

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

【讨论】:

以上是关于与接口相关的访问修饰符的主要内容,如果未能解决你的问题,请参考以下文章

Java中各种(类方法属性)访问修饰符与修饰符的说明

Java中各种(类方法属性)访问修饰符与修饰符的简单说明

c++类不声明访问修饰符 默认是啥

Java修饰符

Java中的修饰符

为啥接口成员没有访问修饰符? [复制]