【问题标题】:c# - Expression overload as parameterc# - 表达式重载作为参数
【发布时间】:2011-04-08 14:38:36
【问题描述】:

我想找到一种方法将表达式(如果可能,编译)作为参数传递给函数。 表达式将始终返回相同的类型。我想将该表达式(函数)保存为参数。

如果可能的话,一个(简短的)示例将非常感激。 :-) 不知道有没有可能。

更多信息:输入是一个表达式,其中只有返回类型应该是固定的。我需要一种方法来定义这种原型。

方法调用示例:

public delegate double[] ValueRetreiverFunc(params object[] anyNumberOfParams);

public class Class1
{
    public double[] Func()
    {
        double[] values = new double[1];
        values[0] = 2.0;
        return values;
    }
}

public class Class2
{
    public double[] Func(int n)
    {
        double[] values = new double[n];
        for (int c = 0; c < n; c++)
        {
            values[c] = 3.0;
        }
        return values;
    }
}

public class ClassTest
{
    public ValueRetreiverFunc ValueRetreiverFunc { get; set; }

    public void SetValueRetreiverFunc(ValueRetreiverFunc valueRetreiverFunc)
    {
        ValueRetreiverFunc = valueRetreiverFunc;
    }

    static void Test()
    {
        ClassTest classTest = new ClassTest();
        Class1 class1 = new Class1();
        Class2 class2 = new Class2();
        classTest.SetValueRetreiverFunc(()=> class1.Func());
        DoProcessArrayOfDouble(classTest.ValueRetreiverFunc());

        classTest.SetValueRetreiverFunc(()=> class2.Func(7));
        DoProcessArrayOfDouble(classTest.ValueRetreiverFunc());
    }
}

【问题讨论】:

  • 您最好使用反射检查该方法,因为您可以在那里轻松地提供动态参数数组。
  • 那么,您是说希望能够将 Func() 或 Func(int) 作为同一个参数传递给方法?
  • 致 aswyer :谢谢,我可能会这样做。但我想知道 Expression 类是否不适合?
  • 致 Tejs:部分正确。的种类。我认为不止于此。它更像是一个表达式,因为参数的值在赋值时是固定的。可能是我的样本不够好。

标签: c# lambda delegates overloading func


【解决方案1】:

我望向远方。我只需要使用“Func”。它就像一个魅力。 这是我更正的样本...

public class Class1
{
    public double[] GetValues()
    {
        double[] values = new double[1];
        values[0] = 2.0;
        return values;
    }
}

public class Class2
{
    public double[] GetValues(int n)
    {
        double[] values = new double[n];
        for (int c = 0; c < n; c++)
        {
            values[c] = 3.0;
        }
        return values;
    }
}

public class ClassTest
{
    public Func<double[]> ValueRetreiverFunc;


    public void SetValueRetreiverFunc(Func<double[]> valueRetreiverFunc)
    {
        ValueRetreiverFunc = valueRetreiverFunc;
    }

    public static void Test()
    {
        ClassTest classTest = new ClassTest();
        Class1 class1 = new Class1();
        Class2 class2 = new Class2();
        classTest.SetValueRetreiverFunc(() => class1.GetValues());
        DoProcessArrayOfDouble(classTest.ValueRetreiverFunc());

        classTest.SetValueRetreiverFunc(() => class2.GetValues(7));
        DoProcessArrayOfDouble(classTest.ValueRetreiverFunc());
    }

    static void DoProcessArrayOfDouble(double[] doubleArray)
    {
        foreach(double d in doubleArray)
        {
            Debug.Print(d.ToString());
        }
    }

}

【讨论】:

    【解决方案2】:

    我唯一能想到的就是这样——不要尝试使用委托,而是定义一个接口,每个实现都会返回它想要的任何东西。

    public interface IDoubleReturningClass
    {
         double[] DoSomething(params object[] anyNumberOfParams);
    }
    
    public class Class1 : IDoubleReturningClass
    {
         public double[] DoSomething(params object[] anyNumberOfParams)
         {
             double[] values = new double[1];
             values[0] = 2.0;
             return values;
         }
    }
    
    public class Class2 : IDoubleReturningClass
    {
         public double[] DoSomething(params object[] anyNumberOfParams)
         {
             double[] values = new double[n];
             for (int c = 0; c < n; c++)
             {
                 values[c] = 3.0;
             }
             return values;
         }
    }
    
    public class ClassTest
    {
          public double[] Values { get; set; }
    
          public void SetValues(IDoubleReturningClass item)
          {
                 Values = item.DoSomething( /* Your Params */);
          }
    }
    

    【讨论】:

    • 谢谢 Tejs。我想过这个问题。但是界面无法完成这项工作。这是因为表达式在某个时刻被定义为一个固定值,但在我们调用这个函数时应该是相同的。接口无法记住该值。只需一个表达式即可(Lambda 或其他类型)。
    【解决方案3】:

    解决我的同事奥马尔向我展示的问题的另一种方法...... 只需委托...由于编译器的 lambda 解析...

    public class TestDelegate
    {
        public delegate double[] ValueRetreiverFunc();
        // or  public Func<double[]> ValueRetreiverFunc;
    
        public class Class1
        {
            public double[] Func()
            {
                double[] values = new double[1];
                values[0] = 2.0;
                return values;
            }
        }
    
        public class Class2
        {
            public double[] Func(int n)
            {
                double[] values = new double[n];
                for (int c = 0; c < n; c++)
                {
                    values[c] = 3.0;
                }
    
                return values;
            }
        }
    
        public class ClassTest
        {
            public ValueRetreiverFunc ValueRetreiverFunc { get; set; }
    
            public void SetValueRetreiverFunc(ValueRetreiverFunc valueRetreiverFunc)
            {
                ValueRetreiverFunc = valueRetreiverFunc;
            }
    
            public static void Test()
            {
                ClassTest classTest = new ClassTest();
                Class1 class1 = new Class1();
                Class2 class2 = new Class2();
    
                classTest.SetValueRetreiverFunc(() => class1.Func());
                DoProcessArrayOfDouble(classTest.ValueRetreiverFunc());
                classTest.SetValueRetreiverFunc(() => class2.Func(7));
                DoProcessArrayOfDouble(classTest.ValueRetreiverFunc());
            }
    
            static void DoProcessArrayOfDouble(double[] doubleArray)
            {
                foreach (double d in doubleArray)
                {
                    Debug.Print(d.ToString());
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多