如何在C#中保存成员变量的选择?

时间:2016-07-26 21:28:54

标签: c# reference

我正在使用具有以下成员变量的类

class SomeClass
{
    int    idx0_value;
    int    idx1_value;
    int    idx2_value;

    //...
}

我无法改变这门课程的结构。

我正在使用此类的实例来检查先前选择的索引,并使用一些if-else语句为变量分配相应的值:

if(indexIFoundEarlier == 0)
    valueIWant = aSomeClass.idx0_value;
else if(indexIFoundEarlier == 1)
    valueIWant = aSomeClass.idx1_value;
else
    valueIWant = aSomeClass.idx2_value;

这似乎效率很低。

在C ++中,我可以有效地存储对相关成员的引用,但在C#中这是不可能的,我已经阅读了相关的各种线程。

在不改变“SomeClass”结构的情况下,是否有更好的(更高效的读取)方式来缓存我所做的选择?

3 个答案:

答案 0 :(得分:0)

您可以使用委托......

class SomeClass {

   int idx0_value;
   int idx1_value;
   int idx2_value;

   private Func<int> selection;

   private void SetSelection( int choice ) {
      switch( choice ) {
      case 0:
         selection = () => idx0_value;
         break;
      case 1:
         selection = () => idx1_value;
         break;
      case 2:
         selection = () => idx2_value;
         break;
      }
   }

   private int GetSelectionAgain() {
      return selection?.Invoke() ?? -1;
   }
}

答案 1 :(得分:0)

  

然而,这似乎效率很低。在C ++中我可以有效地   存储对相关成员的引用,但在C#中,这不是   可能,我已经阅读了各种各样的主题。

这不是低效的,在我看来,使用switch语句对于这种情况来说是你唯一合理的选择。使用反射或任何类型的委派的开销将高于仅仅执行if-else语句或switch语句。

//same concept as what you posted but as a switch statement
switch( indexIFoundEarlier ) 
{
  case 0:
     valueIWant = idx0_value;
     break;
  case 1:
     valueIWant = idx1_value;
     break;
  default:
     valueIWant  = idx2_value;
     break;
}

答案 2 :(得分:0)

我会使用扩展程序。它有效吗?这是主观的,直到它与某些东西相比。但它是可读的,这很重要。如果你的逻辑很简单并且有人出现并且以复杂的方式完成它,那么首先他们会多次阅读它,假设它们必须丢失一些东西。然后,当他们意识到它正在做一些简单的事情时,他们可能想知道为什么不能简单地完成它。

重构代码时会发生这种情况。我们遇到了一些复杂的东西(甚至可能是我们写下并忘记的东西),当我们理解它时,我们会对自己说:“这就是它的全部吗?”然后用更简单的东西替换它。

public static class SomeClassExtensions
{
     public static int GetValueFromIndex(this SomeClass someClass, int index)
     {
         if(index == 0) return someClass.idx0_value;
         if(index == 1) return someClass.idx1_value;
         return someClass.idx2_value;
     }
}

var value = aSomeClass.GetValueFromIndex(indexIFoundEarlier);