Open sandboxFocusImprove this doc

AR0104: [Internal] Applied to a Declaration Other Assemblies Cannot See

Severity Error
Reported by PostSharp
Message Cannot use [Internal] on <Kind> <Declaration> because the <Kind> cannot be seen from other assemblies. [Internal] applies only to public or protected declarations of public types.

Cause

The InternalAttribute constraint keeps other assemblies from using a declaration that must be public for technical reasons. It has a purpose only on a declaration that other assemblies can see: a public, protected or protected internal member of a type that is itself visible outside of its assembly. When the declaration is private, internal or private protected, or belongs to such a type, C# already keeps other assemblies away from it, and PostSharp reports AR0104 on the declaration.

PostSharp itself rejects the most direct cases before this check: applying [Internal] to a member that is not public reports PS0091. AR0104 remains for a member whose own visibility is public but whose type is not, as in the following example, where DiscountCalculator is internal.

using System;
using PostSharp.Constraints;

namespace Errors.AR0104_Error;

internal class DiscountCalculator
{
    // This method is public, but its class is internal, so other assemblies cannot use it anyway.
    [Internal]
    public decimal Apply( decimal subtotal ) => subtotal * 0.9m;
}

public class OrderService
{
    public decimal GetTotal( decimal subtotal ) => new DiscountCalculator().Apply( subtotal );
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( $"Total: {new OrderService().GetTotal( 200m ):0.00}" );
    }
}
error AR0104: AR0104_Error.cs(10,20): Cannot use [Internal] on method Errors.AR0104_Error.DiscountCalculator.Apply because the method cannot be seen from other assemblies. [Internal] applies only to public or protected declarations of public types.

Resolution

  • When the declaration does not need to be visible outside of its assembly, remove [Internal]: the internal keyword already gives the protection.
  • When the type must be public for technical reasons, for example because a serializer or a framework requires it, make the type public and keep [Internal] on the member.

In the following example, DiscountCalculator is public, and [Internal] keeps other assemblies from calling Apply.

using System;
using PostSharp.Constraints;

namespace Errors.AR0104_Fixed;

// The class is public, so [Internal] is what keeps other assemblies from using the method.
public class DiscountCalculator
{
    [Internal]
    public decimal Apply( decimal subtotal ) => subtotal * 0.9m;
}

public class OrderService
{
    public decimal GetTotal( decimal subtotal ) => new DiscountCalculator().Apply( subtotal );
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( $"Total: {new OrderService().GetTotal( 200m ):0.00}" );
    }
}
Total: 180.00

See Also

Reference

InternalAttribute

Other Resources

Controlling Component Visibility Beyond Private and Internal