Ben Keeping
2012-Apr-03 15:13 UTC
[Ironruby-core] mixing in a C# interface which declares generic return types
Hi, I''m trying to mixin a C# interface into a ruby class, in order to use it as a mock. My Ruby class : class MockFoo include IFoo end The C# interface : public interface IFoo { T Get<T>(); // this is OK IEnumerable<T> GetAll(); // this fails } When calling MockFoo.new, I get the following error : Method System.Runtime.CompilerServices.CallSite`1[System.Func`4[System.Runtime.CompilerServices.CallSite,IronRuby.Runtime.RubyContext,System.Object,System.Collections.Generic.IEnumerable`1[T]]] Create(System.Runtime.CompilerServices.CallSiteBinder) contains generic parameters (ArgumentError) System.Core:0:in `ValidateMethodInfo'' System.Core:0:in `Call'' System.Core:0:in `BindCore'' ./features/registration/send_verification_email/send_verification_email_steps.rb:18 features\registration\send_verification_email\send_verification_email.feature:9:in `When I register'' Its OK for methods like : T Get() or T DoStuff(T bla) But whenever I try to return a collection of T : IEnumerable<T> GetAll(); it fails. Any ideas ? Cheers, Ben -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20120403/9efad665/attachment.html>
Orion Edwards
2012-Apr-03 21:03 UTC
[Ironruby-core] mixing in a C# interface which declares generic return types
As far as I can tell, this is simply not supported. I don''t know the reason why. My guess is that when calling Get<T>, IronRuby has to do some work to figure out what the return value of T should be. When calling GetAll<T>, There''s even more work that has to be done to propagate the T back into IEnumerable<T>... I''ve done this kind of reflection work in C# before and it kind of sucks, so I''m not super surprised it''s not handled. It''s a bit of an odd thing to be doing in IronRuby anyway, because the ruby language has no concept of generics, and therefore no way to express the extra type data they provide... it''s kind of a mismatch. Given public interface IFoo { T Get<T>(); } public static void CallGet<T>(IFoo foo) { Console.WriteLine(foo.Get<T>()); } and a ruby mock object: class MockFoo include IFoo def get puts "get called... but we have no idea what T is" return 12 # hopefully T was a fixnum or something convertible end end -- the code does work, you can invoke CallGet<int> or CallGet<string> from C# supplying the ruby mock object, but the ruby get method has no way to know what T is, which will likely lead to other problems. FYI, hoisting the generic up to the interface declaration works fine in all situations, because ruby no longer has to infer the generic T on the fly for every method call. public interface IFoo<T> { T Get(); IEnumerable<T> GetAll(); } class MockFoo include IFoo.of(Fixnum) def get puts "get called..." 12 end def get_all puts "get all called..." System::Array.of(Fixnum).new( [1,2,3] ) end end ______________________________________________________ Orion Edwards | Technical Leader PHONE +64 7 838 9800 | FAX +64 7 838 9801 | EMAIL orion.edwards at gallagher.co | WEB www.gallagher.co From: Ben Keeping <benjaminkeeping at gmail.com> To: ironruby-core at rubyforge.org Date: 04/04/2012 03:24 a.m. Subject: [Ironruby-core] mixing in a C# interface which declares generic return types Sent by: ironruby-core-bounces at rubyforge.org Hi, I''m trying to mixin a C# interface into a ruby class, in order to use it as a mock. My Ruby class : class MockFoo include IFoo end The C# interface : public interface IFoo { T Get<T>(); // this is OK IEnumerable<T> GetAll(); // this fails } When calling MockFoo.new, I get the following error : Method System.Runtime.CompilerServices.CallSite`1[System.Func`4[System.Runtime.CompilerServices.CallSite,IronRuby.Runtime.RubyContext,System.Object,System.Collections.Generic.IEnumerable`1[T]]] Create(System.Runtime.CompilerServices.CallSiteBinder) contains generic parameters (ArgumentError) System.Core:0:in `ValidateMethodInfo'' System.Core:0:in `Call'' System.Core:0:in `BindCore'' ./features/registration/send_verification_email/send_verification_email_steps.rb:18 features\registration\send_verification_email\send_verification_email.feature:9:in `When I register'' Its OK for methods like : T Get() or T DoStuff(T bla) But whenever I try to return a collection of T : IEnumerable<T> GetAll(); it fails. Any ideas ? Cheers, Ben_______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20120404/c576eb6d/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: image/gif Size: 3465 bytes Desc: not available URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20120404/c576eb6d/attachment-0001.gif>