IronRuby вызывает методы расширения C# — ошибка — совместимость в .NET 3.5

Я написал метод расширения для DataGridView, который называется HideColumns.

public static class Extensions
{
    public static void HideColumns(this DataGridView dataGridView, params string[] columnNames)
    {
        foreach (string str in columnNames)
        {
            if (dataGridView.Columns[str] != null)
            {
                dataGridView.Columns[str].Visible = false;
            }
        }
    }

}

Я передаю свою сетку в сценарий IronRuby как переменную с именем main_grid.

Когда мой скрипт вызывает main_grid.HideColumns("FirstName","LastName"), скрипт взрывается с ошибкой в ​​неопределенном методе Script "HideColumns" для System.Windows.Forms.DataGridView:System::Windows::Forms::DataGridView

Методы расширения, похоже, работают нормально с С#. Что дает?


person BuddyJoe    schedule 23.09.2009    source источник


Ответы (3)


FWIW, IronRuby 1.1 (требуется .net 4) предоставляет метод using_clr_extensions - как указано в примечаниях к выпуску, он активирует все методы расширения, определенные для классов, определенных в данном пространстве имен, независимо от сборки, в которой они определены; сборки, загруженные в будущем, которые определяют методы расширения в активированном пространстве имен, будут автоматически отображаться в правильных типах, например:

load_assembly "System.Core"
using_clr_extensions System::Linq

# ...

products.
  where(lambda { |p| p.units_in_stock == 0 }).
  each { |x| puts x.product_name }

В примечаниях к выпуску также указан целый набор примеров по адресу http://github.com/ironruby/ironruby/blob/master/Languages/Ruby/Samples/Linq/101samples.rb

person Steve Gilham    schedule 06.04.2011

Метод расширения — это просто синтаксический сахар, вам нужно будет вызвать его как:

Extensions.HideColumns(main_grid, "FirstName", "LastName")

в качестве альтернативы создайте новый класс в C#, производный от DataGridView, и добавьте метод:

public class DataGridViewExt : DataGridView  
{
    public void HideColumns(params string[] columnNames)
    {
        foreach (string str in columnNames)
        {
            if (this.Columns[str] != null)
            {
                this.Columns[str].Visible = false;
            }
        }
    }        
}

и используйте этот класс, а не класс System.Windows.Forms в своей форме.

person JDunkerley    schedule 23.09.2009
comment
Могу ли я расширить DataGridView (добавить сахар) со стороны Ruby в версии 3.5? Как мне это сделать? - person BuddyJoe; 23.09.2009
comment
Не верьте, самым простым способом было бы получить класс из DataGridView на С# и добавить метод расширения в качестве обычного метода экземпляра (обновит ответ) - person JDunkerley; 23.09.2009
comment
Хм. В порядке. Я попробую это. +1 - я всегда немного нервничаю по поводу расширения классов визуальными представлениями. Много ли вы знаете о взаимодействии .NET 4.0 и IronRuby? Будут ли у меня тогда другие варианты? - person BuddyJoe; 23.09.2009
comment
Не думайте, что это поможет, я думаю, что динамические вещи больше подходят для С#, вызывающего динамические языки, а не наоборот. - person JDunkerley; 23.09.2009

Поскольку вы упомянули об этом в комментариях к ответу JDunkeryly, вот как вы расширите сетку со стороны рубина. Просто откройте класс и добавьте метод (работает только со стороны ruby).

class System::Windows::Forms::DataGridView
  def hide_columns(*columnNames)
    column_names.each do |cn|
      self.columns[cn].visible = false
    end
  end
end

Что касается предложения использовать метод расширения напрямую, ключевое слово params болезненно для IronRuby. Вам нужно построить типизированный массив с вашими аргументами и передать его. Вы не можете просто обернуть рубиновые строки в рубиновый массив. Я сделал это ранее сегодня в блоге сообщение. Но если у вас есть более плавный способ справиться с этим, пожалуйста, дайте мне знать.

person Ball    schedule 23.09.2009