| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot perform a post-compilation static cast from type <SourceType> to type <TargetType>: cannot assign <SourceType> to <TargetType>. |
Cause
An interface that an aspect introduces into a class is not visible to the C# compiler, so the source code cannot convert an instance of the class to this interface with a normal cast. The Cast<TSource, TTarget>(TSource) method fills this gap: the C# compiler accepts any pair of reference types, and PostSharp checks the conversion at build time, after the aspects have been applied, and then removes the call.
PostSharp reports PS0087 when <SourceType>, the first type argument of the call, cannot be assigned to <TargetType>, the second type argument, in the woven assembly. The usual cause is that no aspect introduces <TargetType> into <SourceType>: the aspect is not applied to this class, or it introduces another interface. The message is reported on the line of the call.
In the following example, the [Describable] aspect introduces the IDescribable interface into Customer, but it is not applied to Supplier.
using System;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.PS0087_Error;
public interface IDescribable
{
string Describe();
}
[PSerializable]
[IntroduceInterface( typeof(IDescribable) )]
public class DescribableAttribute : InstanceLevelAspect, IDescribable
{
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
[Describable]
public class Customer
{
}
public class Supplier
{
}
public static class Program
{
public static void Main()
{
IDescribable customer = Post.Cast<Customer, IDescribable>( new Customer() );
Console.WriteLine( customer.Describe() );
// The aspect is not applied to Supplier, so Supplier does not implement IDescribable.
IDescribable supplier = Post.Cast<Supplier, IDescribable>( new Supplier() );
Console.WriteLine( supplier.Describe() );
}
}
error PS0087: PS0087_Error.cs(38,9): Cannot perform a post-compilation static cast from type Errors.PS0087_Error.Supplier to type Errors.PS0087_Error.IDescribable: cannot assign Errors.PS0087_Error.Supplier to Errors.PS0087_Error.IDescribable.
Resolution
- Apply the aspect that introduces
<TargetType>to<SourceType>, directly or by multicasting. - When the aspect is applied, check that it introduces
<TargetType>and not another interface, for example with IntroduceInterfaceAttribute. - When the conversion is not meant to depend on an aspect, use a normal cast instead of Cast<TSource, TTarget>(TSource).
In the following example, the aspect is also applied to Supplier.
using System;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.PS0087_Fixed;
public interface IDescribable
{
string Describe();
}
[PSerializable]
[IntroduceInterface( typeof(IDescribable) )]
public class DescribableAttribute : InstanceLevelAspect, IDescribable
{
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
[Describable]
public class Customer
{
}
// The aspect introduces IDescribable into Supplier too.
[Describable]
public class Supplier
{
}
public static class Program
{
public static void Main()
{
IDescribable customer = Post.Cast<Customer, IDescribable>( new Customer() );
Console.WriteLine( customer.Describe() );
IDescribable supplier = Post.Cast<Supplier, IDescribable>( new Supplier() );
Console.WriteLine( supplier.Describe() );
}
}
Instance of Customer
Instance of Supplier
See Also
Reference
Cast<TSource, TTarget>(TSource)
IntroduceInterfaceAttribute
Other Resources