| 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]: theinternalkeyword 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
Other Resources
Controlling Component Visibility Beyond Private and Internal