calling constructors of C# generics

223 views
Skip to first unread message

cees van Kemenade

unread,
Feb 25, 2018, 5:40:07 AM2/25/18
to clojure-clr

I would like to call constructors on generic, for example to create a Dicttionary<Int,String> for C# interoperability.  Is there an easy way to do this in Clojure-clr?
Currently I only see two options:
  1. Create wrrappers as static functions in C# and include the resulting DLL for usage Clojure-clr 
  2. Build a constructor based on an eval.
Option 2 involves usage of Eval to create a constructor:

user=> (.AssemblyQualifiedName (.GetType (hlp/to-int32 5)))
"System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
user=> (def disConstr (symbol "System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561989],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]."))
#'user/disConstr
user=> (eval (list disConstr))
{}
user=> (type *1)
System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
user=>

As you see I get my Dictionary of the correct type. Is there a standard way to achieve the same result in clojure-clr?
If not, I shall can make a clean implementation of the above and share it as a lib if there is interest.

Cees.

dmiller2718

unread,
Feb 27, 2018, 11:03:14 AM2/27/18
to clojure-clr
Check out https://github.com/clojure/clojure-clr/wiki/Specifying-types for hints on doing this.

for your particular example (and I'm away from any REPL, so just typing without verification here):

(|System.Collections.Generic.Dictionary`2[System.Int, System.String]|.)

should work

dmiller2718

unread,
Feb 27, 2018, 11:09:03 AM2/27/18
to clojure-clr
I built type name support directly on how CLR refers to things internally.
I would like eventually to support something more like what you can do in C#, for example.
Load the DLLs (equivalent to referencing), import namespaces, maybe allow aliases, and get to

(|Dictionary<Int32,String>|.)

Doing so would mean defining the syntax for typenames, making sure all cases are handled, figuring out importing, etc.
|-quoting would still be necessary because you'd still have some special characters (square or angle brackets) at the least to deal with things like generic type args.



And I see a typo in my example.  Should be 
(|System.Collections.Generic.Dictionary`2[System.Int32, System.String]|.)

cees van Kemenade

unread,
Mar 3, 2018, 1:22:12 AM3/3/18
to clojure-clr
Hi David,

Thanks for your fast response.  As I live in a different time-zone I rolled my own solution as I missed your clear Wikispaces document.
The solution you mention with |-quoting certainly is the clean an superior solution in most ordinary cases.

My solution is a dynamic solution which might bring value in the case that you need to determine the type at RunTime. Although it might be that you also have a cleaner solution for that use-case too.  I attached my solution below for those who are interested:

-------------------------
(ns vinzi.DotNet-interop
  (:require [clojure.string :as str]))


(defn create-generic-constructor-symbol
  [fullBaseName & tps]
  (let [tps           (map #(if (isa? (class %) System.RuntimeType) % (class %)) tps)
        tpsQualified  (map #(str \[ (.AssemblyQualifiedName %) \]) tps)]
    (->> (str fullBaseName \` (count tps) \[ (str/join "," tpsQualified) \]\.)
         (symbol ))))

(defn call-generic-constructor
  [constructorSymbol & args]
  (eval (cons constructorSymbol args)))



(defn test-it
  []
  (let [cs (create-generic-constructor-symbol "System.Collections.Generic.Dictionary" System.Int32 System.String)]
    (println " Created constructior-symbol: " cs)
    (let [obj (call-generic-constructor cs )]
      (println "\n\nReceived object of type: " (class obj))
      obj)))
-----------------------
Reply all
Reply to author
Forward
0 new messages