问题
I have written an Extension Method off of DataGridView called 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;
}
}
}
}
I pass my grid into an IronRuby script as a variable called main_grid
When my script calls main_grid.HideColumns("FirstName","LastName") the script blows up with Error in Script undefined method 'HideColumns' for System.Windows.Forms.DataGridView:System::Windows::Forms::DataGridView
The extension methods seem to work okay from C#. What gives?
回答1:
FWIW, IronRuby 1.1 (needs .net 4) provides the using_clr_extensions
method -- as noted in the release notes this activates all extension methods defined on classes defined in a given namespace, regardless of the assembly they are defined in; assemblies loaded in the future that define extension methods in the activated namespace will automatically appear on the correct types, like this:
load_assembly "System.Core"
using_clr_extensions System::Linq
# ...
products.
where(lambda { |p| p.units_in_stock == 0 }).
each { |x| puts x.product_name }
The release notes also point at a whole set of examples at http://github.com/ironruby/ironruby/blob/master/Languages/Ruby/Samples/Linq/101samples.rb
回答2:
The extension method is just syntatic sugar, you will need to call it as:
Extensions.HideColumns(main_grid, "FirstName", "LastName")
alternatively create a new class in C# which derives from DataGridView and add the method:
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;
}
}
}
}
and use this class rather than the System.Windows.Forms class on your form.
回答3:
Since you mentioned it in the comments to JDunkeryly's answer, here's how you'd extend the grid from the ruby side. Just open the class and add a method (only works from the ruby side).
class System::Windows::Forms::DataGridView
def hide_columns(*columnNames)
column_names.each do |cn|
self.columns[cn].visible = false
end
end
end
As far as the suggestion to use the extension method directly, the params keyword is painful to IronRuby. You need to build a typed array with your arguments and pass it. You can't just wrap your ruby strings in a ruby array. I've pulled this off earlier today in a blog post. But if you have a smoother way to handle that, please let me know.
来源:https://stackoverflow.com/questions/1466217/ironruby-calling-c-sharp-extension-methods-error-compatibility-in-net-3-5