Reputation: 33
I am confused over the below paragraph found in https://learn.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.
Could anyone help to give an example of the last sentence? If the class is internal, then no instance of the class can be created outside the assembly. How is it possible that one can access a member of such class from outside the assembly, even if the member is declared public?
Thanks
Upvotes: 1
Views: 184
Reputation: 156504
If the class is internal, then no instance of the class can be created outside the assembly.
Actually, the class could be created outside the assembly using reflection.
More commonly, it's possible that the class could be created inside the assembly and then passed to methods outside the assembly, but simply cast as an interface or parent class which is publicly visible.
For an example, consider the following C# expression:
((Expression<Func<int, bool>>) (i => i == 0))
The Body
property of this expression is cast as an Expression
, but the actual type of that particular Expression is a LogicalBinaryExpression
, which is a class that's internal to the System.Core library.
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; }
}
}
Notice how the public Type
and NodeType
properties are overridden by this type. So even though this type is internal
and you can never cast it to a LogicalBinaryExpression
in your own code, it still has public members which you can access via the Expression
type.
Console.WriteLine(((Expression<Func<int, bool>>) (i => i == 0)).Body.Type.ToString());
// Output: System.Boolean
Upvotes: 3
Reputation: 38757
Imagine you create the following service and interface:
public interface IFoo
{
void Bar();
}
internal class ConcreteFoo : IFoo
{
public void Bar()
{
Console.WriteLine("Hello from my concrete foo!");
}
}
You then expose a factory:
public class Factory
{
public IFoo CreateFoo()
{
return new ConcreteFoo();
}
}
The Bar
method is implementing the interface requirement of void Bar();
in IFoo
. While consumers can't instantiate a ConcreteFoo
, it's possible for other entities within your library to create and return a ConcreteFoo
boxed as an IFoo
(which is public), thereby allowing access to the member in the consuming code.
Upvotes: 4