Open sandboxFocusImprove this doc

PS0169: Value in XML Cannot Be Converted to the Type of the Member

Severity Error
Reported by PostSharp
Message Error parsing the value of member '<Element>.<Member>': cannot convert '<Value>' into type '<MemberType>'.

Cause

The Multicast element of a postsharp.config file adds aspects or other multicast attributes to the project, as Adding Aspects Using XML describes. Each XML attribute of a child element sets the public field or property of the same name of the attribute class, and PostSharp converts the text of the XML attribute into the type of this member.

PostSharp reports PS0169 when this conversion fails. <Element> is the local name of the XML element, <Member> the name of the XML attribute, <Value> its text, and <MemberType> the type of the member; for the intrinsic types, the message shows their IL name, such as int32 for int. The location of the message is the XML attribute in the postsharp.config file. The usual causes are:

  • A number contains a unit, a thousands separator or a decimal comma. PostSharp converts numbers with the Convert class and the invariant culture.
  • A Boolean is not true or false.
  • The value of an enumeration is not the name or the number of one of its members.
  • A Type is not the name of a type that PostSharp can find.

In the following example, postsharp.config sets the ThresholdMilliseconds property, an int, to 500 ms.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Multicast xmlns:my="clr-namespace:Errors.PS0169_Error;assembly:PS0169_Error">
    <!-- "500 ms" is not an int: the unit is part of the value. -->
    <my:WarnIfSlowAttribute AttributeTargetTypes="Errors.PS0169_Error.OrderService" AttributeTargetMembers="PlaceOrder" ThresholdMilliseconds="500 ms" />
  </Multicast>
</Project>
using System;
using System.Diagnostics;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.PS0169_Error;

// postsharp.config applies this aspect to OrderService.PlaceOrder and sets its ThresholdMilliseconds property.
[PSerializable]
public class WarnIfSlowAttribute : OnMethodBoundaryAspect
{
    // postsharp.config sets this property.
    public int ThresholdMilliseconds { get; set; } = 1000;

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Timing {args.Method.Name} against a threshold of {this.ThresholdMilliseconds} ms." );
        args.MethodExecutionTag = Stopwatch.StartNew();
    }

    public override void OnExit( MethodExecutionArgs args )
    {
        Stopwatch stopwatch = (Stopwatch) args.MethodExecutionTag;

        if ( stopwatch.ElapsedMilliseconds > this.ThresholdMilliseconds )
        {
            Console.WriteLine( $"Warning: {args.Method.Name} took {stopwatch.ElapsedMilliseconds} ms." );
        }
    }
}

public class OrderService
{
    public void PlaceOrder( string product )
    {
        Console.WriteLine( $"Order placed for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Coffee" );
    }
}
error PS0169: postsharp.config(5,121): Error parsing the value of member 'WarnIfSlowAttribute.ThresholdMilliseconds': cannot convert '500 ms' into type 'int32'.

Resolution

Write the value in the format that Including CLR Objects in Configuration gives for the type of the member: a number without unit in the invariant culture, true or false, enumeration members separated by | or +, an assembly-qualified type name, or array items separated by ;.

In the following example, the value is 500.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Multicast xmlns:my="clr-namespace:Errors.PS0169_Fixed;assembly:PS0169_Fixed">
    <!-- The value is a plain int, in the invariant culture. -->
    <my:WarnIfSlowAttribute AttributeTargetTypes="Errors.PS0169_Fixed.OrderService" AttributeTargetMembers="PlaceOrder" ThresholdMilliseconds="500" />
  </Multicast>
</Project>
using System;
using System.Diagnostics;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.PS0169_Fixed;

// postsharp.config applies this aspect to OrderService.PlaceOrder and sets its ThresholdMilliseconds property.
[PSerializable]
public class WarnIfSlowAttribute : OnMethodBoundaryAspect
{
    // postsharp.config sets this property.
    public int ThresholdMilliseconds { get; set; } = 1000;

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Timing {args.Method.Name} against a threshold of {this.ThresholdMilliseconds} ms." );
        args.MethodExecutionTag = Stopwatch.StartNew();
    }

    public override void OnExit( MethodExecutionArgs args )
    {
        Stopwatch stopwatch = (Stopwatch) args.MethodExecutionTag;

        if ( stopwatch.ElapsedMilliseconds > this.ThresholdMilliseconds )
        {
            Console.WriteLine( $"Warning: {args.Method.Name} took {stopwatch.ElapsedMilliseconds} ms." );
        }
    }
}

public class OrderService
{
    public void PlaceOrder( string product )
    {
        Console.WriteLine( $"Order placed for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Coffee" );
    }
}
Timing PlaceOrder against a threshold of 500 ms.
Order placed for Coffee.

See Also

Other Resources

Adding Aspects Using XML
Including CLR Objects in Configuration
Configuring Projects Using postsharp.config