Beginning sometime after PowerShell 5.1 a class implementing IConvertible throws an exception when casting to a string.
Note that in the repro below simply removing : IConvertible is sufficient to restore the ability to cast to string.
```C#
//type.cs
using System;
public class C : IConvertible
{
public readonly string Value = null;
public C(string v) { Value = v; }
override public String ToString() {return Value; }
public TypeCode GetTypeCode() { return Value.GetTypeCode(); }
public object ToType(Type conversionType, IFormatProvider provider) { return ((IConvertible)Value).ToType(conversionType, provider); }
public bool ToBoolean(IFormatProvider provider) { return ((IConvertible)Value).ToBoolean(provider); }
public byte ToByte(IFormatProvider provider) { return ((IConvertible)Value).ToByte(provider); }
public char ToChar(IFormatProvider provider) { return ((IConvertible)Value).ToChar(provider); }
public DateTime ToDateTime(IFormatProvider provider) { return ((IConvertible)Value).ToDateTime(provider); }
public decimal ToDecimal(IFormatProvider provider) { return ((IConvertible)Value).ToDecimal(provider); }
public double ToDouble(IFormatProvider provider) { return ((IConvertible)Value).ToDouble(provider); }
public short ToInt16(IFormatProvider provider) { return ((IConvertible)Value).ToInt16(provider); }
public int ToInt32(IFormatProvider provider) { return ((IConvertible)Value).ToInt32(provider); }
public long ToInt64(IFormatProvider provider) { return ((IConvertible)Value).ToInt64(provider); }
public sbyte ToSByte(IFormatProvider provider) { return ((IConvertible)Value).ToSByte(provider); }
public float ToSingle(IFormatProvider provider) { return ((IConvertible)Value).ToSingle(provider); }
public string ToString(IFormatProvider provider) { return Value.ToString(provider); }
public ushort ToUInt16(IFormatProvider provider) { return ((IConvertible)Value).ToUInt16(provider); }
public uint ToUInt32(IFormatProvider provider) { return ((IConvertible)Value).ToUInt32(provider); }
public ulong ToUInt64(IFormatProvider provider) {return ((IConvertible)Value).ToUInt64(provider); }
}
```powershell
Add-Type -Path "$PSScriptRoot\type.cs"
$c = [C]::new('value')
$c.ToString()
[string]$c
value
value
value
OperationStopped: C:\test.ps1:5
Line |
5 | [string]$c
| ~~~~~~~~~~
| Unable to cast object of type 'C' to type 'System.String'.
value
value
Name Value
---- -----
PSVersion 7.0.0-rc.2
PSEdition Core
GitCommitId 7.0.0-rc.2
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0.}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
I think it is .Net Core issue.
If you can create C# repo please report to .Net Core repo. Otherwise we should investigate in depth before report there.
@iSazonov I thought that might be the case too. But casting to string in C# like the following doesn't seem to be permitted by either compiler I've tried with Core 3.1 or Framework 4.7.2 (those links are dotnetfiddle repros):
```C#
public class C : IConvertible {...}
public class Program
{
public static void Main()
{
C c = new C("value");
String s = (String)c; // Compilation error: Cannot convert type 'C' to 'string'
}
}
```
I think that error makes sense in C# since there is no conversion operator defined for C on String.
Having the corresponding restriction in PowerShell, however, seems odd since [string]$anyObject seems to succeed for any type other than those for which IConvertible is implemented.
I'm... pretty sure this is a PowerShell thing. IConvertible has specific conversion methods associated with it, and those methods all assume the input is numeric as far as I recall.. so I think this object is making it to those methods and then failing, or we're missing a specific IConvertible conversion path that doesn't assume the input is a number.
If you look through the LanguagePrimitives.cs file for references to ConvertIConvertible you should come up with a few good places to start.
It works in PowerShell-7.0.0-preview.1 but not later.
I found https://github.com/PowerShell/PowerShell/pull/9893 for the time but I am not sure that this is the cause of the error.
/cc @daxian-dbw