Richard
Richard

Reputation: 455

Reflection with multiple parameter types

I have a database table that contains two text fields: methodname and methodparameters. The values from the table are stored in a dictionary.

Each methodname value corresponds to an image filter method in a c# class, and each methodparameters is a comma-delimited list of numeric values.

I want to use reflection to call methodname with its corresponding list of methodparameters.

Here is a portion of image filter class:

namespace ImageFilters
{
  public class Filters
  {

    private static Bitmap mBMP;

    public Bitmap BMP { 
        get
        {
            return mBMP;
        }
        set
        {
            mBMP = value;
        }
    }

    public static void FilterColors(string[] paramlist)
    {

        mBMP = FilterColors(mBMP, 
                            Convert.ToInt16(paramlist[0].ToString()),
                            Convert.ToInt16(paramlist[1].ToString()),
                            Convert.ToInt16(paramlist[2].ToString()),
                            Convert.ToInt16(paramlist[3].ToString()),
                            Convert.ToInt16(paramlist[4].ToString()),
                            Convert.ToInt16(paramlist[5].ToString())
                            );

    }

    public static Bitmap FilterColors(Bitmap bmp, int RedFrom,int RedTo, 
                       int GreenFrom, int GreenTo, int BlueFrom, int BlueTo,
                       byte RedFill = 255, byte GreenFill = 255, 
                       byte BlueFill = 255, bool FillOutside = true)
    {
        AForge.Imaging.Filters.ColorFiltering f = new AForge.Imaging.Filters.ColorFiltering();
        f.FillOutsideRange = FillOutside;
        f.FillColor = new AForge.Imaging.RGB(RedFill, GreenFill, BlueFill);
        f.Red = new AForge.IntRange(RedFrom, RedTo);
        f.Green = new AForge.IntRange(GreenFrom, GreenTo);
        f.Blue = new AForge.IntRange(BlueFrom, BlueTo);
        return f.Apply(bmp);
    }

Here is the code I am using that uses Reflection:

    private static void ApplyFilters(ref Bitmap bmp, 
                      dictionaries.FilterFields pFilters)
    {

        for(int i = 0; i < pFilters.Detail.Length; i++)
        {
            Type t = typeof(ImageFilters.Filters);
            MethodInfo mi = t.GetMethod(pFilters.Detail[i].MethodName);
            ImageFilters.Filters f = new ImageFilters.Filters();
            f.BMP = bmp;

            string[] parameters = pFilters.Detail[i].MethodParameters.Split(',');
            mi.Invoke(f, parameters);
        }
    }

Each image is processed with no filters, and with two sets of different filters (from the database). The following loop handles the filters:

        foreach (KeyValuePair<string, dictionaries.FilterFields> item 
                 in dictionaries.Filters)
        {
            bmp = OriginalBMP;

            ApplyFilters(ref bmp, item.Value);

        }

My problem is that when it hits ApplyFilters in the loop, it gives me the following error:

"Method not found: 'Void ImageFilters.Filters.set_BMP(System.Drawing.Bitmap)'. It does not even allow me to step into the ApplyFilters method.

I definitely do not have a method called "set_BMP" in my database table.

Any ideas?

Upvotes: 4

Views: 282

Answers (2)

T McKeown
T McKeown

Reputation: 12857

Your BMP is not a method, it is a property. Get the property then get the .SetMethod of the property.

PropertyInfo pi = type.GetProperty("BMP");
System.Reflection.MethodInfo mi = pi.SetMethod;

string[] parameters = pFilters.Detail[i].MethodParameters.Split(',');
mi.Invoke(f, parameters);

Upvotes: 0

Michael Gunter
Michael Gunter

Reputation: 12811

The error you're getting is a JIT error. At runtime, you are attempting to call ApplyFilters. The runtime then tries to compile the ApplyFilters method from MSIL to machine code. At that point in time, it sees that you're using a property called BMP on the Filters class, but it can't find it (or can't find the setter). Therefore it can't compile the method and can't call into it, which is why your breakpoint isn't being hit.

It appears the BMP property (or its setter) does not exist at runtime. This usually happens because a different version of the assembly is being loaded at runtime -- you compile it with one version that has this property, but when running it, the referenced assembly doesn't contain that property.

Double-check that the assemblies that exist in the directory are up-to-date and are the correct versions you're expecting.

Upvotes: 1

Related Questions