2

I have C# class in an external DLL which I cannot modify. Two of the classes in the library are defined as follows which I need to use in my Powershell script.

public class MyCsharpClass<TKey, TValue> : ISomeBaseClass<TKey, TValue>
{
    public MyCsharpClass(string path, ISomeBaseTranslator<TKey, TValue> translator)
    {
        ...
    }
}
...
...
public class MyByteTranslatorCSharpClass: ISomeBaseTranslator<byte[], byte[]>
{
    ...
}

I want to create instance of MyCsharpClass in Powershell script as follows:

$MyType = [MyCsharpClass[byte[],byte[]]]::new($Path, [MyByteTranslatorCSharpClass]::new())

But the above line fails with below error. I can just enter type name in PS ISE command window and get the same error.

PS C:\> [MyCsharpClass[byte[],byte[]]]
At line:1 char:30
+ [MyCsharpClass[byte[],byte[]]]
+                                                                     ~
Unexpected token ']' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

Below line works fine though showing me the type info of my class when I just use byte type for TKey:

PS C:\> [MyCsharpClass[byte,byte[]]]

IsPublic IsSerial Name                                     BaseType                                                                                                                                         
-------- -------- ----                                     --------                                                                                                                                         
True     False    MyCsharpClass                           System.Object 

It seems the first closing bracket ']' for my Key type of byte[] confuses Powershell that type definition is being closed and so it raises error when it observes Unexpected token ']' in the end of expression.

I also tried to replace byte[] type with System.Collections.Generic.List type which works fine now for declaring a type.

PS C:\> MyCsharpClass[System.Collections.Generic.List[System.Byte],System.Collections.Generic.List[System.Byte]]]

IsPublic IsSerial Name                                     BaseType                                                                                                                                         
-------- -------- ----                                     --------                                                                                                                                         
True     False    MyCsharpClass                           System.Object 

However the constructor invocation fails this time while passing instance of MyByteTranslatorCSharpClass as second argument in constructor (at the end of below line).

$MyType = [MyCsharpClass[System.Collections.Generic.List[System.Byte],System.Collections.Generic.List[System.Byte]]]::new($Path, [MyByteTranslatorCSharpClass]::new())

This gives exception of 'System.Management.Automation.MethodException: Cannot convert argument "translator", with value: "MyByteTranslatorCSharpClass", for ".ctor" to type "ISomeBaseTranslator[System.Collections.Generic.List1[System.Byte],System.Collections.Generic.List1[System.Byte]]"

Please let me know in this context, how can I create instance of MyCsharpClass with byte[] type for TKey and TValue generic arguments in Powershell. Please note that I can neither change the DLL side nor do I have its source.

0

1 Answer 1

3

This appears to be a type name parsing bug.

Fortunately, you can easily work around this by "qualifying" the type parameter literals with an extra pair of square brackets ([]) :

[MyCsharpClass[[byte[]],[byte[]]]]::new(...)

... or by constructing the concrete type directly using reflection:

$myType = [MyCsharpClass`2].MakeGenericType(@([byte[]],[byte[]]))

$myType::new(...)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick response :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.