2012-03-16 1 views
0

Итак, я пишу приложение C#, используя .net/C# 4.0 У меня есть метод, который использует нестандартный тип и словарь. Я использую это для разных вещей, но по какой-то причине я не могу придумать способ инкапсуляции логики. Проблема этой линииПоиск способа повторного использования моей функции, которая изменяется одним малым способом

if (FastIntParse.FastParse(_dict[_Rule.Key].hourly_data[a].PropertyA) > 
_Rule.Value) 

В другом применении может быть

if (FastIntParse.FastParse(_dict[_Rule.Key].hourly_data[a].PropertyB) > 
_Rule.Value) 

Единственным, что меняется в различных случаях является Property я использую, чтобы сравнить со значением правила. По какой-то причине я не могу придумать способ его повторного использования, потому что у меня нет значения для передачи какой-либо функции, поскольку значение выводится в функции. Как я могу написать функцию для абстрагирования от нее, нужно знать, какое значение ей нужно получить и передать эту информацию, то есть передать ее, какое свойство ей нужно будет проверить, а не значение указанного свойства.

int a; 
    for (int z= 0;z<=2;z++) 
    { 
    a = (z * z) * 24; 
    for (; (a%24) <= _Rule.AlertEndTime; a++) 
    { 
     if (FastIntParse.FastParse(_dict[_Rule.Key].hourly_data[a].PropertyA) > 
_Rule.Value) 
     { 

      EnqueueRuleTrigger(_Rule); 
      break; 
     } 
    } 
    } 

Я продолжаю переписывать этот метод инлайн везде, где мне нужно его с правильной собственности .... это, очевидно, весьма расточительно и любые изменения должны быть сделаны во многих местах. Заранее спасибо

+0

в случае, если я не ясно, я даже не Обский ject для свойства вне цикла. Я хотел бы инкапсулировать что-то, что содержит логику цикла [которая не изменяется] вместе с возможностью предоставления настраиваемого свойства методу. Вещь, если у меня есть 4 условия, которые точно совпадают, за исключением того, какое свойство они оценивают, поэтому я только что скопировал и вставил весь этот код и изменил ссылку на свойство. Еще хуже, что каждый из этих 4 имеет 3 варианта, один из которых, если использует a>, a <и an = So, у меня действительно этот метод слегка изменен 12 раз. – Jordan

ответ

0

Сделайте свою функцию взять лямбда-аргумент и передать его _ => _.PropertyA, _ => _.PropertyB и т.д .:

void CheckAndEnqueueRulesByProperty (Func<YourObject, string> propertyGetter) 
{ 
    ... 
    if (FastIntParse.FastParse (propertyGetter (
      _dict[_Rule.Key].hourly_data[a])) > _Rule.Value) 
    { 
     ... 
    } 
    ... 
} 

Если у вас есть много типов объектов для проверки с той же логикой, делают эту функцию родовым.

+0

Я не могу получить доступ до тех пор, пока не попаду в цикл, потому что PropertyA и PropertyB являются свойствами объекта в массиве [В словаре], который является индексом, который я не знаю, пока не встану в цикле. Вся эта вещь - это «функция», которую я продолжаю вставлять inline. Я хочу создать функцию из этого, где я могу в принципе сказать, что использовать свойство для объекта, на котором у меня пока нет ссылки. Эта ссылка на свойство должна быть передана от вызывающего. Если ваш ответ покрыл это извините, я не совсем понял это, поскольку я немного новичок в Lambdas .... – Jordan

1

Вы можете использовать выражение, а затем вытащить свойство внутри метода, а затем использовать отражение, чтобы связать это до объекта в методе

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<PropertyBag> bags = new List<PropertyBag>() 
            { 
             new PropertyBag() {Property1 = 1, Property2 = 2}, 
             new PropertyBag() {Property1 = 3, Property2 = 4} 
            }; 

     Runme(x => x.Property1, bags); 
     Runme(x => x.Property2, bags); 

     Console.ReadLine(); 


    } 

    public static void Runme(Expression<Func<PropertyBag, int>> expression, List<PropertyBag> bags) 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     var prop = memberExpression.Member as PropertyInfo; 

     bags.ForEach(bag => 
       Console.WriteLine(prop.GetValue(bag, null)) 
      ); 
    } 
} 


public class PropertyBag 
{ 
    public int Property1 { get; set; } 
    public int Property2 { get; set; } 
} 

}

1

решить проблему с доступом к различным свойствам и с использованием различной булевой-функция (<,>, ==) вы могли бы использовать делегат, как это:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 

namespace ConsoleApplication1 
{ 
    delegate bool CompareFunction(Fii test, Foo item); 

    class Program 
    { 
     static List<Foo> list = new List<Foo>() { 
      new Foo() { PropertyA = 0, PropertyB = 9 }, 
      new Foo() { PropertyA = 1, PropertyB = 10 } 
     }; 
     static Fii test = new Fii() { PropertyA = 1 }; 

     static void Main(string[] args) 
     { 
      Bar(list, delegate(Fii item1, Foo item2) { return item2.PropertyA < item1.PropertyA; }); 
      Bar(list, delegate(Fii item1, Foo item2) { return item2.PropertyB > item1.PropertyA; }); 
      Bar(list, delegate(Fii item1, Foo item2) { return item2.PropertyA == item1.PropertyA; }); 
      Console.ReadLine(); 
     } 

     static void Bar(List<Foo> list, CompareFunction cmp) 
     { 
      foreach (Foo item in list) 
       if (cmp(test, item)) 
        Console.WriteLine("true"); 
       else 
        Console.WriteLine("false"); 
     } 
    } 

    class Foo 
    { 
     public int PropertyA { get; set; } 
     public int PropertyB { get; set; } 
    } 

    class Fii 
    { 
     public int PropertyA { get; set; } 
    } 
}