【问题标题】:Finding a way to reuse my function that varies in one small way找到一种重用我的功能的方法,该功能以一种小的方式变化
【发布时间】:2012-03-16 06:24:57
【问题描述】:

所以我正在编写一个 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)

在各种情况下唯一不同的是我用来与规则值进行比较的属性。出于某种原因,我想不出一种方法来重用它,因为我没有传递给某个函数的值,因为该值是在函数中派生的。我如何编写一个函数来抽象它需要知道它需要派生哪个值并将该信息传递给它,即传递它需要检查的属性而不是所述属性的值。

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

我不断地在需要的地方用适当的属性重写这个方法......这显然是非常浪费的,并且需要在许多地方进行任何更改。 提前致谢

【问题讨论】:

  • 如果我不清楚,我什至没有循环外属性的对象引用。我想封装一些包含循环逻辑[不会改变]的东西,以及为方法提供自定义属性的能力。如果我有 4 个条件完全相同,除了它们评估的属性,所以我刚刚复制并粘贴了整个代码并更改了属性引用。更糟糕的是,这 4 个中的每一个都有 3 个变体,其中一个 if 使用 >、a

标签: c# .net lambda anonymous-function code-reuse


【解决方案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; }
}

}

【讨论】:

    【解决方案2】:

    要解决访问不同属性和使用不同布尔函数(、==)的问题,您可以使用如下委托:

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

    【讨论】:

      【解决方案3】:

      让你的函数接受一个 lambda 参数并将其传递给 _ =&gt; _.PropertyA_ =&gt; _.PropertyB 等:

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

      如果您要使用相同的逻辑检查多种类型的对象,请将此函数设为通用。

      【讨论】:

      • 在循环中之前我无法访问 _ 因为 PropertyA 和 PropertyB 是数组中对象的属性[在字典中] 谁的索引在我进入循环之前我不知道.这整件事是我不断粘贴的“函数”。我想从中创建一个函数,我基本上可以告诉它为我还没有引用的对象使用属性。该属性引用必须从调用者传入。如果你的回答涵盖了这个抱歉我不太明白,因为我对 Lambdas 有点陌生......
      猜你喜欢
      • 1970-01-01
      • 2022-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 2012-04-30
      • 2023-04-09
      相关资源
      最近更新 更多