2014-01-13 9 views
4

У меня есть таблица базы данных, которая содержит два текстовых поля: methodname и methodparameters. Значения из таблицы хранятся в словаре.Отражение с несколькими типами параметров

Каждое значение имени метода соответствует методу фильтра изображений в классе C#, а каждый из параметров метода представляет собой список числовых значений с разделителями-запятыми.

Я хочу использовать отражение для вызова метода name с его соответствующим списком параметров метода.

Вот часть класса изображения фильтра:

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); 
    } 

Вот код, я использую, который использует 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); 
     } 
    } 

Каждое изображение обрабатывается без каких-либо фильтров, и с двумя наборами различных фильтров (из базы данных). Следующий цикл обрабатывает фильтры:

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

      ApplyFilters(ref bmp, item.Value); 

     } 

Моя проблема заключается в том, что, когда она попадает ApplyFilters в петле, он дает мне следующую ошибку:

«Метод не нашел:«Пустота ImageFilters.Filters.set_BMP (System.Drawing.Bitmap). Он даже не позволяет мне уйти в метод ApplyFilters.

Я определенно не имеют метод, называемый „set_BMP“ в моей таблице базы данных.

Любые идеи?

+2

set_BMP - это сеттер для свойства, а не метод – thumbmunkeys

+0

@ Рихард, вам нужно сказать нам, что такое 'pFilters.Detail [i] .MethodName' со 100% уверенностью. (распечатайте его на консоль или что-то еще, скопируйте и вставьте значение). –

+0

* >> Это даже не позволяет мне войти в метод ApplyFilters. * Можете ли вы поставить точку останова там? Но да, я не думаю, что вы можете обращаться к разработчикам свойств как к методам, вам нужно получить к ним доступ в качестве свойств. –

ответ

1

Ошибка, которую вы получаете, является ошибкой JIT. Во время выполнения вы пытаетесь позвонить по номеру ApplyFilters. Затем среда выполнения пытается скомпилировать метод ApplyFilters от MSIL до машинного кода. В этот момент он видит, что вы используете свойство BMP класса Filters, но оно не может найти его (или не может найти установщик). Поэтому он не может скомпилировать метод и не может вызвать его, поэтому ваша точка останова не попадает.

Похоже, что свойство BMP (или его сеттер) не существует во время выполнения. Обычно это происходит из-за того, что во время выполнения загружается другая версия сборки - вы скомпилируете ее с одной версией, которая имеет это свойство, но при ее запуске ссылка на сборку не содержит этого свойства.

Дважды проверьте, что сборки, существующие в каталоге, являются актуальными и являются правильными версиями, которые вы ожидаете.

+0

Я сделал чистую и перестроенную, но все же ту же ошибку. – Richard

+0

Все ли фрагменты кода из исходного сообщения в той же сборке? –

+0

И у вас есть несколько артефактов под названием «ImageFilters»? В приведенном выше коде 'ImageFilters' является пространством имен. У вас также есть классы или свойства с именем «ImageFilters»? –

0

Ваш BMP не метод, это свойство. Получите собственность, затем получите .SetMethod свойства.

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

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

Я ни в коем случае не пытаюсь вызвать BMP как метод. У меня нет Set_BMP где-нибудь в моем классе фильтра изображений, и я понятия не имею, откуда оно взялось. – Richard

+0

Это не проблема. Метод «ApplyFilters» - это код, содержащий отражение, а среда выполнения не скомпилирует метод «ApplyFilters». –

+0

Ваш Invoke не вызывает его? Что вызывает ваш вызов? –

Смежные вопросы