InvalidOperationException On generic type
Closed this issue · 5 comments
[JSExport]
public class ProxyArray<T> : ProxyTypeBase, IList<T>, ICollection<T>, IEnumerable<T>
{
private List<T> _raw;
public ProxyArray()
{
_raw = new List<T>();
}
}
//Get Compile Error :
CSC : error NAPI1001: InvalidOperationException : Unknown generic type parameter T in type jj.Jex.Runtime.ProxyTypes.ProxyArray`1 在 Microsoft.JavaScript.NodeApi.Generator.SymbolExtensions.AsType(ITypeSymbol typeSymbol, Type[] genericTypeParameters, Boolean buildType) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Buffer`1..ctor(IEnumerable`1 source) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 在 Microsoft.JavaScript.NodeApi.Generator.SymbolExtensions.AsType(ITypeSymbol typeSymbol, Type[] genericTypeParameters, Boolean buildType) 在 Microsoft.JavaScript.NodeApi.Generator.SymbolExtensions.AsConstructorInfo(IMethodSymbol methodSymbol) 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Buffer`1..ctor(IEnumerable`1 source) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 在 Microsoft.JavaScript.NodeApi.Generator.ModuleGenerator.ExportType(SourceBuilder& s, ITypeSymbol type, String exportName)
So Template Type is not supported now ? Or How I can get those type exported?
Exporting a generic type to JavaScript using static binding ([JSExport]
) is not supported. There is an issue (#298) about reporting a better error message in that case. However it is possible to dynamically load and use any kind of generic types. For more details see https://microsoft.github.io/node-api-dotnet/reference/generics.html
What is your goal with the ProxyArray<T>
type? Are you aware that generic collection interfaces like IList<>
are already marshalled by reference (proxy)? So you can pass an IList<>
or IDictionary<,>
from .NET to JS, and have both .NET and JS code reading and writing items in the same collection. https://microsoft.github.io/node-api-dotnet/reference/arrays-collections.html#generic-interfaces
I want use property set
method to trace the item change event.
OK, to accomplish that you can still implement a ProxyArray<T>
class while exporting it as only a IList<T>
. Something like this:
[JSExport]
public static class ProxyArrayFactory
{
public static IList<int> CreateProxyArrayOfInt() => new ProxyArray<int>();
public static IList<string> CreateProxyArrayOfString() => new ProxyArray<string>();
}
// Not exported
internal class ProxyArray<T> : IList<T>
{
private List<T> _inner = new List<T>();
public T this[int index]
{
get => _inner[index];
set
{
Console.WriteLine($"Setting [{index}] = {value}.");
_inner[index] = value;
}
}
}
In JavaScript the proxies will look and act like JS arrays, but they proxy all calls to .NET via IList<T>
.
const proxyArray = ProxyArrayFactory.createProxyArrayOfInt();
assert(Array.isArray(proxyArray));
I'm closing this because the question was answered and there's another issue tracking a better error message. If you're still having trouble, feel free to reopen this, or open a new issue.