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.edwa...@gallagher.co | WEB www.gallagher.co  




From:   Ben Keeping <benjaminkeep...@gmail.com>
To:     ironruby-core@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-boun...@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@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

<<image/gif>>

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

Reply via email to