This analyzer currently provides the ability to restrict a generic type parameter's substituted types through the provided type constraint attributes. They must be directly specified at the generic type parameter.
Consider for example the following class:
public class C<T>
where T : IComparable<T>
{
// code
}
If the type T should never be substituted by ulong
, the following adjustment must be made:
public class C
<
[ProhibitedTypes(typeof(ulong))]
T
>
On the following code snippet, the analyzer will emit GA0001 on the ulong
word:
new C<ulong>();
It is restricted by the language to include a generic type in the typeof
expression. This means that attempting to restrict types that contain it will not compile. The following example would result in an error:
public class C
<
[ProhibitedTypes(typeof(IComparable<T>))]
T
>
There also is the ability to prohibit any type that inherits the specified prohibited base types. In a similar example, consider the following class:
public class C<T, U>
where T : IEnumerable<U>
{
// code
}
If the type T should never inherit an IList<>
(of any type because of the aforementioned language restriction), the following must be done:
public class C
<
[ProhibitedBaseTypes(typeof(IList<>))]
T,
U
>
On the following code snippet, the analyzer will emit GA0001 on the List<int>
word because List<int>
implements IList<int>
, which is prohibited from the analyzer's type constraints:
new C<List<int>, int>();
Prohibitions aside, some types may be excepted from the rules by permitting them to be used. In the previous example:
public class C
<
[ProhibitedBaseTypes(typeof(IList<>))]
T,
U
>
If IList<int>
can be allowed as a type argument for T, the following modification has to be made:
public class C
<
[PermittedBaseTypes(typeof(IList<int>))]
[ProhibitedBaseTypes(typeof(IList<>))]
T,
U
>
As a result, the example code snippet will not emit any errors:
new C<List<int>, int>();
On a generic element that only supports a collection of types, there is no need to explicitly prohibit the unsupported types. For example,
public T AddSigned
<
[PermittedTypes(typeof(sbyte), typeof(short), typeof(int), typeof(long))]
[OnlyPermitSpecifiedTypes]
T
>
(T left, T right)
where T : IComparable<T>
{
// code
}
In the above function, only the types sbyte
, short
, int
and long
are supported. Using any other type would emit an error, as in the following example:
AddSigned<ulong>(45UL, 76UL);