| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot use [Protected] on <Kind> <Declaration> because the <Kind> is already private or protected, or belongs to a private or protected type. [Protected] applies only to public or internal declarations. |
Cause
The ProtectedAttribute constraint restricts a public or internal declaration to the type that declares it and to the types derived from it, as the protected keyword would, for a declaration that must be public or internal for technical reasons. When the declaration is private or protected, or belongs to a nested type that is private or protected, C# already gives this protection, and PostSharp reports AR0107 on the declaration.
PostSharp itself rejects the most direct cases before this check: applying [Protected] to a private or protected member reports PS0091. AR0107 remains for a member whose own visibility is public or internal but whose nested type is private or protected, as in the following example, where HeaderFormatter is protected.
using System;
using PostSharp.Constraints;
namespace Errors.AR0107_Error;
public class ReportGenerator
{
protected class HeaderFormatter
{
// This method is public, but its class is protected, so C# already restricts it to derived classes.
[Protected]
public string Format( string title ) => $"=== {title.ToUpperInvariant()} ===";
}
public string Generate( string title ) => new HeaderFormatter().Format( title ) + Environment.NewLine + "(no data)";
}
public class SalesReportGenerator : ReportGenerator
{
public string GenerateSales() => new HeaderFormatter().Format( "Sales" ) + Environment.NewLine + "Total: 1250.00";
}
public static class Program
{
public static void Main()
{
Console.WriteLine( new SalesReportGenerator().GenerateSales() );
}
}
error AR0107: AR0107_Error.cs(12,23): Cannot use [Protected] on method Errors.AR0107_Error.ReportGenerator+HeaderFormatter.Format because the method is already private or protected, or belongs to a private or protected type. [Protected] applies only to public or internal declarations.
Resolution
- When the nested type does not need to be visible outside of its containing type and its derived types, remove
[Protected]: theprotectedkeyword already gives the protection. - When the nested type must be public or internal for technical reasons, change its visibility and keep
[Protected]on the member.
In the following example, HeaderFormatter is public, and [Protected] restricts Format to ReportGenerator and its derived classes.
using System;
using PostSharp.Constraints;
namespace Errors.AR0107_Fixed;
public class ReportGenerator
{
// The class is public, so [Protected] is what restricts the method to ReportGenerator and its derived classes.
public class HeaderFormatter
{
[Protected]
public string Format( string title ) => $"=== {title.ToUpperInvariant()} ===";
}
public string Generate( string title ) => new HeaderFormatter().Format( title ) + Environment.NewLine + "(no data)";
}
public class SalesReportGenerator : ReportGenerator
{
public string GenerateSales() => new HeaderFormatter().Format( "Sales" ) + Environment.NewLine + "Total: 1250.00";
}
public static class Program
{
public static void Main()
{
Console.WriteLine( new SalesReportGenerator().GenerateSales() );
}
}
=== SALES ===
Total: 1250.00
See Also
Reference
Other Resources