[rdnzl-devel] Re: RDNZL problem

Iver Odin Kvello iverodin at gmail.com
Mon Feb 4 21:31:10 UTC 2008


> I initial tried to mimic the apropos example and use an EventHandler
> instead of using my callback, but for some reason, RDNZL couldn't find
> the EventHanlder type when I tried to import it from the System namespace.

Did you look in the right assembly? There is a System.dll, a
System.Core.dll and mscorlib, all defining objects in the "System"
namespace. This is good because - well, anyway, you can find
EventHandler like this:

RDNZL-USER 110 > (import-type "System.EventHandler" (load-assembly "mscorlib"))
#<RDNZL::CONTAINER System.Type #xBC2850>

RDNZL-USER 111 > (use-namespace "System")

RDNZL-USER 112 > (new "EventHandler")
#<RDNZL::CONTAINER System.EventHandler #xBC4718>

IMPORT-TYPES adds the assembly-name to the type as a prefix, which is
why that hurts right here; the princess is in another castle.

This thing is currently somewhat of an issue with generic types as
well: In System.Core there is the Func`n type which is very
convenient, but as this is defined in "System.Core.dll" and for
example System.Int32 is defined in "mscorlib.dll", this does not work:

RDNZL-USER 140 > (invoke "System.Type" "GetType"
"System.Func`2[System.Int32,System.Int32]")
Warning: Returning NULL object from .NET call
NIL

This however will work:
RDNZL-USER 142 > (invoke "System.Type" "GetType"
"System.Action`1[System.Int32]")
#<RDNZL::CONTAINER System.Type #xBC45C8>

because both types are in mscorlib.

I'm planning to add some code to handle this case a bit more
elegantly, but this perl-style hack works if this bites:

RDNZL-USER 139 > (invoke "System.Type" "GetType"
(resolve-generic-type '("System.Func" "System.Int32" "System.Int32")))
#<RDNZL::CONTAINER System.Type #xBC46C8>

where resolve-generic-type ensures all types have assembly-qualified
names like so:

(defun resolve-generic-type (generic-type-definition)
  (if (consp generic-type-definition)
      (let* ((type-args (rest generic-type-definition))
             (args (length type-args))
             (resolved-type-args (mapcar #'resolve-generic-type type-args))
             (main-type-name (format nil "~a`~d" (first
generic-type-definition) args))
             (main-type-resolved (resolve-type-name main-type-name))
             ;; The comma separates the full type name of the main
type from the assembly-name,
             ;; we need to add the parameter-type in the middle in
square parenthesis before
             ;; the assembly..
             (comma (position #\, main-type-resolved))
             (pre-type-result (when comma (subseq main-type-resolved 0 comma)))
             (post-type-result (when comma
                                 (subseq main-type-resolved comma
(length main-type-resolved)))))
        (if comma
            (format nil "~a[~{[~a]~^,~}]~a" pre-type-result
resolved-type-args post-type-result)
          (format nil "~a[~{[~a]~^,~}]" main-type-resolved resolved-type-args)))
    (resolve-type-name generic-type-definition)))


Regards, Iver



More information about the rdnzl-devel mailing list