Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用谓词替换';如果';在c#中?_C#_Predicate - Fatal编程技术网

使用谓词替换';如果';在c#中?

使用谓词替换';如果';在c#中?,c#,predicate,C#,Predicate,我读到'if'关键字是邪恶的,最好用谓词来代替if。然后我用谷歌搜索了一下,但还是不明白 有人能举个例子吗?不管他们说什么,如果不是邪恶的话。在某些特定情况下,谓词可能比if(或一组if)更好 比如说, foreach (Foo f in fooList) { if (f.Equals(fooTarget)) { return f; } } 与(.NET 2.0)相比 或(稍后) 除了withinn搜索之外,我自己不会将它们用于直接的“if…else”构

我读到'if'关键字是邪恶的,最好用谓词来代替if。然后我用谷歌搜索了一下,但还是不明白


有人能举个例子吗?

不管他们说什么,如果不是邪恶的话。在某些特定情况下,谓词可能比if(或一组if)更好

比如说,

 foreach (Foo f in fooList) {
     if (f.Equals(fooTarget)) {
        return f;
     }
 }
与(.NET 2.0)相比

或(稍后)


除了withinn搜索之外,我自己不会将它们用于直接的“if…else”构造,因为它也消除了循环构造的需要。比如说

int index = this.listObjects.FindIndex(x => x.PropertyA == objectItem.PropertyA);

List listClass=new List();
//... 还有一些用ClassA类型填充listClass的代码。。。
ClassA tempClassA=listClass.FirstOrDefault()。其中(x=>x.PropertyA==someValue);

但我必须承认,如果对一个项目进行直接比较,那么我使用和“if…else”结构。

它们只是不同而已。谓词比简单的if语句更复杂。谓词基本上是指向方法(委托)的指针,该方法与作为参数的类型相关联,并返回true/false

假设您正在使用泛型,就像泛型列表上的find方法一样,在初始化它之前,它如何知道列表中有哪些类型。因此find方法只使用谓词,不知道如何实现谓词

public T Find(Predicate<T> p)
    {
        //iterate through the collection and return the first match
        IEnumerator<T> enumerator = this.GetEnumerator();

        while (enumerator.MoveNext())
        {
            if (p(enumerator.Current))
            {
                return enumerator.Current;
            }
        }

        return default(T);
    }

例如,每当有这样的循环时:

List<Employee> retiredEmployees = new List<Employee>();
foreach (Employee employee in EmployeeList)
{
    if (employee.IsRetired)
        retiredEmployees.Add(employee);
}
但我相信,在整个辩论中,
谓词
vs
if
只是作为使用OOP和函数式编程vs过程式编程的特例提到的。这个范例可以很容易地推广到任何委托类型(不仅仅是谓词),或者任何使用OOP来替换条件:

例如,如果浏览代码,您可能很容易找到如下代码:

public class Employee
{
    private bool _isRetired;
    private double _amount;
    public double GetPayAmount()
    {
         if (_isRetired)
            return _amount * 0.9;
         else
            return _amount;
    }
}
纯面向对象的支持者会告诉您,您需要立即提取不同类型的员工,并将每个分支处理为不同的子类型,这将删除“邪恶的if语句”

public interface IEmployee
{
   double GetPayAmount();
}

public class Employee : IEmployee
{
   private double _amount;
   public double GetPayAmount()
   {
       return _amount;
   }
}

public class RetiredEmployee : IEmployee
{
   private double _amount;
   public double GetPayAmount()
   {
       return _amount * 0.9;
   }
}

虽然这样维护代码更容易,但第二种情况下的代码量明显增加了一倍。对于这样一个简单的层次结构,在这个阶段几乎不需要进行重构。如果您决定需要更多的特殊情况,那么您的条件可能会变得太复杂,您可以在以后轻松地对其进行重构。

似乎与这个问题有关:(不是重复,只是上下文)这可能也会有所帮助-没有分支的程序确实是一个非常遗憾的程序。没有分支的程序是一件美好的事情。;-)回答得好。我不知道如何将委托分配给谓词。在第一个示例中,您仍然有一个“邪恶的如果”:)我对“如果”没有问题,它提供了一个purpose@Groo-您建议如何在不使用“if”的情况下编写我的find方法?
    static void Main()
    {
        string[] names = { "Lukasz", "Darek", "Milosz" };

        foreach (var item in names)
        {
            if (ContainsL(item))
                 Console.WriteLine(item);
        }

        string match1 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
        //or
        string match2 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
        //or
        string match3 = Array.Find(names, x => x.Contains("L"));


        Console.WriteLine(match1 + " " + match2 + " " + match3);     // Lukasz Lukasz Lukasz
    }
    static bool ContainsL(string name) { return name.Contains("L"); }
someList.FindAll(findShortNames1);
List<Employee> retiredEmployees = new List<Employee>();
foreach (Employee employee in EmployeeList)
{
    if (employee.IsRetired)
        retiredEmployees.Add(employee);
}
retiredEmployees = EmployeeList.FindAll(e => e.IsRetired);
public class Employee
{
    private bool _isRetired;
    private double _amount;
    public double GetPayAmount()
    {
         if (_isRetired)
            return _amount * 0.9;
         else
            return _amount;
    }
}
public interface IEmployee
{
   double GetPayAmount();
}

public class Employee : IEmployee
{
   private double _amount;
   public double GetPayAmount()
   {
       return _amount;
   }
}

public class RetiredEmployee : IEmployee
{
   private double _amount;
   public double GetPayAmount()
   {
       return _amount * 0.9;
   }
}
    static void Main()
    {
        string[] names = { "Lukasz", "Darek", "Milosz" };

        foreach (var item in names)
        {
            if (ContainsL(item))
                 Console.WriteLine(item);
        }

        string match1 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
        //or
        string match2 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
        //or
        string match3 = Array.Find(names, x => x.Contains("L"));


        Console.WriteLine(match1 + " " + match2 + " " + match3);     // Lukasz Lukasz Lukasz
    }
    static bool ContainsL(string name) { return name.Contains("L"); }