[Closed] C# Activator problem
I just tried to modify one to my script that compile C# code from maxscript.
I create a “Microsoft.CSharp.CSharpCodeProvider” bind my files, ect…
Everything working fine until I try to create an instance with arguments.
Activator.CreateInstance always tell me “Runtime error: No method found which matched argument list”
I someone see an error…
-- globalVar is the compiled assembly
fn Create globalVar ClassName args:#() =
(
csBinder = dotNetClass "System.Reflection.Binder"
argArr = dotNetObject "object[]" args.count
for i in 1 to args.count do (argArr.Set (i-1) args[i])
csCulture = dotNetClass "System.Globalization.CultureInfo"
csBinding = dotNetClass "System.Reflection.BindingFlags"
activationAttributes = dotNetObject "System.Object[]" 0
res = globalVar.CreateInstance className true csBinding.CreateInstance csBinder argArr csCulture.InvariantCulture activationAttributes
return res
)
without your c# code no one can tell you what’s going wrong
edited…
wait a sec… i don’t remember the set of arguments for CreateInstance method that you use… check the arguments types
Here’s a snippet to play with, sorry for the imprecision!
The method i want to use is:
.<System.Object>CreateInstance <System.String>typeName <System.Boolean>ignoreCase <System.Reflection.BindingFlags>bindingAttr <System.Reflection.Binder>binder <System.Object[]>args <System.Globalization.CultureInfo>culture <System.Object[]>activationAttributes
fn CompileAssemblyFromSource sources dlls:#("System.dll")=
(
if (classOf sources == string) do (sources = #(sources))
-- create compiler
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
-- add reference to external dlls
for dll in dlls do ( compilerParams.ReferencedAssemblies.Add(dll) )
-- set compiler parameters
compilerParams.GenerateInMemory = true
compilerParams.GenerateExecutable = false
-- compile code
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams sources
-- check for errors
if (compilerResults.Errors.Count == 0) then
( globalVar = compilerResults.CompiledAssembly; return globalVar )
else
(
format "compilation errors:
"
for i in 1 to compilerResults.Errors.Count do
( format "%
" compilerResults.Errors.Item[i-1].ErrorText )
return false
)
)
fn Create Assembly ClassName args:#() =
(
if (Assembly != undefined) do
(
if (args.count < 1) then
( try(return Assembly.CreateInstance className true) catch(return undefined) )
else
(
csBinder = dotNetClass "System.Reflection.Binder"
csCulture = dotNetClass "System.Globalization.CultureInfo"
csBinding = dotNetClass "System.Reflection.BindingFlags"
activationAttributes = dotNetObject "System.Object[]" 0
try(return Assembly.CreateInstance className true csBinding.CreateInstance csBinder args csCulture.InvariantCulture activationAttributes) catch(return undefined)
)
)
)
sources = "using System;
"
sources += "public class testClass
"
sources += "{"
sources += "string name;
"
sources += "public testClass()
"
sources += "{"
sources += "}"
sources += "public testClass(string name)
"
sources += "{"
sources += "this.name = name;"
sources += "}"
sources += "}"
Assembly = CompileAssemblyFromSource sources
testA = create Assembly "testClass"
format "testA:%
" testA
testB = create Assembly "testClass" args:#("blop")
format "testB:%
" testB
ok. the fixed problem is show in red…
Assembly.CreateInstance "testClass" true (dotnetclass "System.Reflection.BindingFlags").CreateInstance (Assembly.GetType "testClass").DefaultBinder #("test") (dotnetclass "System.Globalization.CultureInfo").InvariantCulture #()
you are using in the CreateInstance method the class (“CultureInfo”) where must be an Object
Thanks Denis! Always there to save the day!
I didn’t understand the binder part at first and I hope i will never have to write one.
Didn’t actually understand the use.
When you have a dynamic class or when you don’t know wich type you working with?!
Anyway everything working fine now, just had to convert the args array entering the maxscript function in dotNetObject “object[]”.
if you don’t know the type you can’t create the object. every type has it’s default binder which can be used for instance creation…
binder
Type: System.Reflection.Binder
An object that enables the binding, coercion of argument types, invocation of members, and retrieval of MemberInfo objects via reflection. If binder is null, the default binder is used.
what i didn’t understand was in wich case you would have to override default binder.
But since i never had to use invoke menber or invoke method, I’m probably still too “noobish” with c# to get the concept behind.
Sorry for the misunderstanding.