C# 避免为不同的代码执行重复for循环

C# 避免为不同的代码执行重复for循环,c#,performance,loops,C#,Performance,Loops,我有一个条件,让我们假设例如Animal={Dog,Cat,Elephant} 现在我想用if条件创建一个for循环(不是简单的for循环),在这个for循环中,我根据动物类型编写一些代码,例如: for(int i=0;i<100;i++) { if(some conditions on i) { for(int j =0;j<100;j++) { if(some condition on j) { switch(animalt

我有一个条件,让我们假设例如
Animal={Dog,Cat,Elephant}

现在我想用if条件创建一个for循环(不是简单的for循环),在这个for循环中,我根据动物类型编写一些代码,例如:

for(int i=0;i<100;i++)
{
  if(some conditions on i)
  {
   for(int j =0;j<100;j++)
   {
     if(some condition on j)
     {
       switch(animaltype)
       {  
         case Dog: //call function 1
         case Cat: //call function 2
         case Elephant: //call function 3
       }
     }
   }
  }
}
function1(string s,int age)
function2(float height,bool CanMove)
function3(int legs,string name,string place)
这里的问题是,我重复了代码3次(或作为案例数),这违反了软件设计的一次且仅一次原则

我试图传递一个委托,但我应该调用的3个函数有不同的参数,有人能告诉我一个简单的解决方案吗

编辑 我所说的“不同的论点”是指他们不接受相同数量的论点。 例如:

for(int i=0;i<100;i++)
{
  if(some conditions on i)
  {
   for(int j =0;j<100;j++)
   {
     if(some condition on j)
     {
       switch(animaltype)
       {  
         case Dog: //call function 1
         case Cat: //call function 2
         case Elephant: //call function 3
       }
     }
   }
  }
}
function1(string s,int age)
function2(float height,bool CanMove)
function3(int legs,string name,string place)
我试图传递一个委托,但是我应该调用的3个函数 有不同的论点,谁能告诉我一个简洁的解决方案 案子

创建3个函数,这些函数不带调用现有函数的参数。例如

Func HandleDog = ()=>{function1(param1, param2);};
Func HandleCat = ()=>{function2(param1);};
我试图传递一个委托,但是我应该调用的3个函数 有不同的论点,谁能告诉我一个简洁的解决方案 案子

创建3个函数,这些函数不带调用现有函数的参数。例如

Func HandleDog = ()=>{function1(param1, param2);};
Func HandleCat = ()=>{function2(param1);};

试着这样做:

switch (animaltype)
{
case Dog :
    for(int i=0;i<100;i++)
    {
      if(some conditions on i)
      {
       for(int j =0;j<100;j++)
       {
         if(some condition on j)
         {
           //call function 1
         }
       }
      }  
    }
//-------------
case Cat :
    for(int i=0;i<100;i++)
    {
      if(some conditions on i)
      {
       for(int j =0;j<100;j++)
       {
         if(some condition on j)
         {
           //call function 2
         }
       }
      }  
    }
//----------------------
case Elephant :
    for(int i=0;i<100;i++)
    {
      if(some conditions on i)
      {
       for(int j =0;j<100;j++)
       {
         if(some condition on j)
         {
           //call function 3
         }
       }
      }  
    }
}
void ExecuteLoop(Func callback)
{
    for(int i=0;i<100;i++)
    {
        if(some conditions on i)
        {
            for(int j =0;j<100;j++)
            {
                if(some condition on j)
                {
                    callback();
                }
            }
        }  
    }
}

switch (animaltype)
{
case Dog:
    ExecuteLoop(dogCallback);
    break;
case Cat:
    ExecuteLoop(catCallback);
    break;
case Elephant:
    ExecuteLoop(elephantCallback);
    break;
}
switch (animaltype)
{
case Dog:
    ExecuteLoop(() => { dogCallback(1, 2, 3); });
    break;
case Cat:
    ExecuteLoop(() = > { catCallback( "argument 1", "arg 2" ); });
    break;
case Elephant:
    ExecuteLoop(() => { elephantCallback(i, j, k); });
    break;
}

这将使用不接受任何参数(因此符合
ExecuteLoop
方法的要求)但调用接受任意数量变量类型参数的方法。

请尝试以下操作:

switch (animaltype)
{
case Dog :
    for(int i=0;i<100;i++)
    {
      if(some conditions on i)
      {
       for(int j =0;j<100;j++)
       {
         if(some condition on j)
         {
           //call function 1
         }
       }
      }  
    }
//-------------
case Cat :
    for(int i=0;i<100;i++)
    {
      if(some conditions on i)
      {
       for(int j =0;j<100;j++)
       {
         if(some condition on j)
         {
           //call function 2
         }
       }
      }  
    }
//----------------------
case Elephant :
    for(int i=0;i<100;i++)
    {
      if(some conditions on i)
      {
       for(int j =0;j<100;j++)
       {
         if(some condition on j)
         {
           //call function 3
         }
       }
      }  
    }
}
void ExecuteLoop(Func callback)
{
    for(int i=0;i<100;i++)
    {
        if(some conditions on i)
        {
            for(int j =0;j<100;j++)
            {
                if(some condition on j)
                {
                    callback();
                }
            }
        }  
    }
}

switch (animaltype)
{
case Dog:
    ExecuteLoop(dogCallback);
    break;
case Cat:
    ExecuteLoop(catCallback);
    break;
case Elephant:
    ExecuteLoop(elephantCallback);
    break;
}
switch (animaltype)
{
case Dog:
    ExecuteLoop(() => { dogCallback(1, 2, 3); });
    break;
case Cat:
    ExecuteLoop(() = > { catCallback( "argument 1", "arg 2" ); });
    break;
case Elephant:
    ExecuteLoop(() => { elephantCallback(i, j, k); });
    break;
}

这使用不接受任何参数(因此符合
ExecuteLoop
方法的要求)但调用接受任意数量的变量类型参数的方法。

要扩展Robert和William提供的答案,我个人认为:

        Action animalMethod;

        switch (animalType)
        {
            case Dog:
                animalMethod = new Action(() => CallMethod1(animal as Dog));
                break;
            case Cat:
                animalMethod = new Action(() => CallMethod1(animal as Dog));
                break;
            case Elephant:
                animalMethod = new Action(() => CallMethod1(animal as Dog));
                break;
            default:
                throw new Exception("Unknown Animal");
        }

        for (var i = 0; i < 100; i++)
        {
            if (some conditions on i)
            {
                for (var j = 0; j < 100; j++)
                {
                    if (some condition on j)
                    {
                        animalMethod();
                    }
                }
            }
        }
动作动物法;
开关(动物类型)
{
个案犬:
animalMethod=新动作(()=>CallMethod1(动物如狗));
打破
案例类别:
animalMethod=新动作(()=>CallMethod1(动物如狗));
打破
案例大象:
animalMethod=新动作(()=>CallMethod1(动物如狗));
打破
违约:
抛出新异常(“未知动物”);
}
对于(变量i=0;i<100;i++)
{
if(i上的某些条件)
{
对于(var j=0;j<100;j++)
{
if(j上的某些条件)
{
动物方法();
}
}
}
}

要详细介绍罗伯特和威廉提供的答案,我个人认为这更干净:

        Action animalMethod;

        switch (animalType)
        {
            case Dog:
                animalMethod = new Action(() => CallMethod1(animal as Dog));
                break;
            case Cat:
                animalMethod = new Action(() => CallMethod1(animal as Dog));
                break;
            case Elephant:
                animalMethod = new Action(() => CallMethod1(animal as Dog));
                break;
            default:
                throw new Exception("Unknown Animal");
        }

        for (var i = 0; i < 100; i++)
        {
            if (some conditions on i)
            {
                for (var j = 0; j < 100; j++)
                {
                    if (some condition on j)
                    {
                        animalMethod();
                    }
                }
            }
        }
动作动物法;
开关(动物类型)
{
个案犬:
animalMethod=新动作(()=>CallMethod1(动物如狗));
打破
案例类别:
animalMethod=新动作(()=>CallMethod1(动物如狗));
打破
案例大象:
animalMethod=新动作(()=>CallMethod1(动物如狗));
打破
违约:
抛出新异常(“未知动物”);
}
对于(变量i=0;i<100;i++)
{
if(i上的某些条件)
{
对于(var j=0;j<100;j++)
{
if(j上的某些条件)
{
动物方法();
}
}
}
}

这就是方法存在的原因。另外,不要担心
开关的性能。如果您能给出一个更完整的示例,这会有所帮助。关键在于你需要对动物做什么方面的差异。。。(我强烈怀疑委托是正确的解决方案,但如果没有完整的问题示例,我们无法给出更完整的解决方案示例…)另一件事是,您永远不应该过早地优化代码。我不相信你真的通过重新安排执行来提高性能。如果有的话,你只会使可读性变差。开关语句在这里不会成为性能问题,它变成ASM中的简单JMP。还考虑该动物是否应该是类而不是枚举(或字符串或它在这里的任何东西),函数是该类的一种方法。如果不知道具体的方法是什么,很难说这里的情况是否如此——这就是方法存在的原因。另外,不要担心
开关的性能。如果您能给出一个更完整的示例,这会有所帮助。关键在于你需要对动物做什么方面的差异。。。(我强烈怀疑委托是正确的解决方案,但如果没有完整的问题示例,我们无法给出更完整的解决方案示例…)另一件事是,您永远不应该过早地优化代码。我不相信你真的通过重新安排执行来提高性能。如果有的话,你只会使可读性变差。开关语句在这里不会成为性能问题,它变成ASM中的简单JMP。还考虑该动物是否应该是类而不是枚举(或字符串或它在这里的任何东西),函数是该类的一种方法。如果不知道具体的方法是什么,很难说情况是否如此鉴于我们从问题中获得的信息量,这可能是最好的解决方案鉴于我们从问题中获得的信息量,这可能是最好的解决方案,我们的解决方案的代码行数完全相同:28行。只是一个有趣的事实!不过,不同之处在于,我将for循环保留在分配回调delegat的相同方法中