在运行时为访问List中的元素分配一个公式

本文关键字:一个 分配 元素 运行时 访问 List | 更新日期: 2023-09-27 18:18:04

这个场景是我有两种不同类型的情况-情况1和情况2。对于情形1和情形2,我分别有一个特定的startIndex、endIndex和一个用于访问List元素的公式。

现在对于赋值startIndex和endIndex,我更喜欢正常的切换情况,但是我对访问元素的公式感到困惑。对于情况1,表示为List[a +i],对于情况2,表示为List[a + (i-b)]。一种方法是使用像这样的for循环

for(int i=0;;i++)
{ 
     if(case is 1)
        then f=a+i 
     else if(case 2)
        then f=a+(i-b) 
}

我想使用委托。然而,据我所知,它们需要全球化。操作不返回值。可以使用Func,但是一个表达式/公式只接受一个元素(int),另一个接受3个元素。我需要这样的东西,比如匿名函数可以在运行时从切换情况中分配上述任何公式(因为这种情况可能会在未来增加)。

谢谢。

在运行时为访问List中的元素分配一个公式

我想使用委托。然而,据我所知,他们需要

这是不正确的(实际上,c#中没有真正的全局变量,因为每个变量都需要封装在对象中)。在引用包含该类型代码的程序集之后,公共委托类型确实对所有代码可见,但是这种类型的变量可以是私有的。

在你的情况下,我的建议是从案例号到委托的某种映射。如果每个案例最多有一个委托,那么使用Dictionary<TKey, TValue>是一个好主意。该字典可以作为私有变量存储在方法所在的类中。

public class MyClass
{
    private Dictionary<int, Delegate> _delegateMapping = new Dictionary<int, Delegate>;
}

有几种方法可以在构造函数中向字典中添加元素:传递已经填充的字典,传递委托数组,在构造函数中创建这些委托。无论哪种方式,您最终都会得到一个Delegate类型的字典,因此您需要使用强制转换才能在代码中正确使用它们。

 for (int i = 1; i < _delegateMapping.Count; i++)
 {
     switch (i)
     {
         case 1:
             var f = (Action<int>)_delegateMapping[1];
             f(i);
             break;
         case 2:
             var f = (Action<int, int>)_delegateMapping[2];
             f(i, a);
             break;
     }
 }   
当然,我在这里是即兴发挥。

需要注意的是,如果委托的类型在字典中发生了变化,则必须在switch语句中相应地修改强制类型转换。否则,如果不存在隐式强制转换,则会得到运行时异常。

大家好,非常感谢大家的反馈。我终于和Func一起找到了解决办法。这就是我的代码。我必须稍微调整一下Func的用法。我做了几乎所有我必须在函数中使用的变量,作为我写这些函数的函数的全局/局部。如果我没能恰当地解释我的问题,我道歉。

        int i = -1;
        Func<int,int> formula = null;
        switch(f)
        {
            case 1:
            {
                formula = new Func<int,int>(index => { return i; });
            }
            break;
            case 2:
            {
                formula = new Func<int, int>( index => { return s- (i * c); } );//here s and c are global variables.
            }
            break;
        }
        i = startIndex;
        while(i < endIndex)
        {
            var Obj= List[formula.Invoke(i)];
            //my code goes here
            i++;
        }

让我知道我的解决方案是否正确w.r.t性能,逻辑,c#编程等。:)

编辑::@usr和@Kapol我尝试了你建议的方法,并尝试像这样即兴编写代码。

    private Dictionary<int, Func<int[], int>> indexFormulae;
    private void assignDelegates()
    {
        indexFormulae = new Dictionary<int, Func<int[], int>>();
        indexFormulae.Add(0, getFormula_1);
        indexFormulae.Add(1, getFormula_2);
    } 
    private void someFunction(int sp)
    {
        int i = 0;
        Func<int[], int> formula = null;
        indexFormulae.TryGetValue(formation,out formula);
        i = startIndex;
        while (i < endIndex)
        {
            int[] intValues = new int[] {i,sp,globalVar };
            var Obj = List[formula.Invoke(intValues)];
            //My code here
            i++;
        }
    }
    private int getFormula_1(params int[] intValues)
    {
        return intValues[0];
    }
    private int getIndex_Vertical(params int[] intValues)
    {
        return intValues[1] - (intValues[0] * intValues[2]); 
    }
因此,现在我可以在这个类的任何地方使用这两个getFormula方法,而不是保持它们是匿名的。而且我认为我会坚持使用参数,因为将来我可能会在其他函数中使用N个int参数