根据数据库中的数据动态调用 C# 方法

发布于 2024-10-20 07:33:19 字数 194 浏览 6 评论 0原文

我的老板让我研究一个计算引擎。实际上,用户将拥有一个可以执行计算的数据表。他们还能够根据我们强制执行的某些限制构建自己的计算(构建的计算将存储在数据库中)

是否可以根据数据库中存储的内容调用 C# 中的特定方法?因此,如果数据库说,计算应该执行标准偏差。当我们从数据库中获取该信息时,是否可以调用 C# 中的标准差方法?

我希望这一点很清楚。

My boss has asked me to look into a calculation engine. Effectively, the user will have a table of data that can have calculations be performed on. They will also be able to build their own calculations based on certain restrictions we enforce (the built calculations will then be stored in the database)

Is it possible to call a specific method in C#, dependent upon what is stored in the database? So if the database says, a calculation should perform a standard deviation. When we get that information from the database, is it then possible to call a standard deviation method that we will have in C#?

I hope this is clear.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

咆哮 2024-10-27 07:33:19

考虑到将对您的数据执行的少量/已知操作量,我会选择根据从数据库检索的数据手动编码这些操作。为了可扩展性/可维护性,最好为此创建适当的设计,而不是使用简单的 switch 语句。我猜策略模式会满足您的需求。

正如其他人所述,您可以使用 反射,调用数据库中指定的方法。这种方法的问题是数据库中的数据与方法签名紧密相关。与第一种方法相比,这种方法的可维护性较差,但确实可以通过最少的代码调整实现良好的可扩展性。另一个缺点是使用 MethodInfo.Invoke() 的速度相当慢。

如果您选择反射,但发现 Invoke() 方法太慢,我可以推荐 Jon Skeet 的这篇文章 解释了如何将 MethodInfo 转换为委托实例。这大大提高了速度。我最近为此编写了使用表达式树的通用实现

总而言之,选项 1 似乎仍然最适合您的目的。

Considering the small/known amount of operations which will be executed on your data, I would opt to manually code these operations, based on the data retrieved from the database. For extendability/maintainability, it's best to create a proper design for this instead of using a simple switch statement. I'm guessing the Strategy pattern will suit your needs.

As others stated, you could use reflection, to call the methods as specified in the database. The problem with this approach is the data in your database is strongly linked to the method signatures. This is less maintainable than the first approach, but does allow for great extendability with minimal code adjustments. Another downside is using MethodInfo.Invoke() is rather slow.

If you would opt for reflection, but find the Invoke() approach to be too slow, I can recommend this article by Jon Skeet which explains how to convert a MethodInfo into a delegate instance. This gives a major speed boost. I wrote a generic implementation using expression trees for this recently.

All in all, it seems like option 1 is still the best for your purposes.

我恋#小黄人 2024-10-27 07:33:19

是的,这是可能的;它称为反射,它是一个标准的 C# 功能。网上有很多教程;这是一些非常简单的示例代码:

using System;
using System.Reflection;

class CallMethodByName
{
   string name;

   CallMethodByName (string name)
   {
      this.name = name;
   }

   public void DisplayName()      // method to call by name
   {
      Console.WriteLine (name);   // prove we called it
   }

   static void Main()
   {
      // Instantiate this class
      CallMethodByName cmbn = new CallMethodByName ("CSO");

      // Get the desired method by name: DisplayName
      MethodInfo methodInfo = 
         typeof (CallMethodByName).GetMethod ("DisplayName");

      // Use the instance to call the method without arguments
      methodInfo.Invoke (cmbn, null);
   }
}

http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string< /a>

Yes, this is possible; it's called reflection and it's a standard C# feature. Many tutorials exist out on the web; here's some pretty simple example code:

using System;
using System.Reflection;

class CallMethodByName
{
   string name;

   CallMethodByName (string name)
   {
      this.name = name;
   }

   public void DisplayName()      // method to call by name
   {
      Console.WriteLine (name);   // prove we called it
   }

   static void Main()
   {
      // Instantiate this class
      CallMethodByName cmbn = new CallMethodByName ("CSO");

      // Get the desired method by name: DisplayName
      MethodInfo methodInfo = 
         typeof (CallMethodByName).GetMethod ("DisplayName");

      // Use the instance to call the method without arguments
      methodInfo.Invoke (cmbn, null);
   }
}

http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string

心不设防 2024-10-27 07:33:19

您可以将操作存储在数据库中并使用 Microsoft.CSharp .CSharpCodeProvider 即时编译代码。

请参阅此处的示例:在运行时执行代码

You can store operations in DB and use Microsoft.CSharp.CSharpCodeProvider to compile code on-the-fly.

See sample here: Execute code at runtime

萌面超妹 2024-10-27 07:33:19

是的,您可以使用反射来做到这一点。您可以编写一个包含用户可以执行的所有操作的类,然后动态调用其方法。

public static class UserOperations
{
    public static decimal Average(IEnumerable<decimal> source)
    {
        return source.Average();
    }

    // Other methods
}

class Program
{
    static void Main(string[] args)
    {
        // The operation retrieved from the db
        string operation = "Average";
        // The items on which the operations should be performed
        decimal[] items = { 22m, 55m, 77m };

        object result = typeof(UserOperations).GetMethod(operation).Invoke(null, new object[] { items });
        Console.WriteLine(result);
        Console.ReadLine();
    }
}

Yes, you can do it using Reflection. You could write a class that contains all the operations that user could do and then call its methods dynamically.

public static class UserOperations
{
    public static decimal Average(IEnumerable<decimal> source)
    {
        return source.Average();
    }

    // Other methods
}

class Program
{
    static void Main(string[] args)
    {
        // The operation retrieved from the db
        string operation = "Average";
        // The items on which the operations should be performed
        decimal[] items = { 22m, 55m, 77m };

        object result = typeof(UserOperations).GetMethod(operation).Invoke(null, new object[] { items });
        Console.WriteLine(result);
        Console.ReadLine();
    }
}
夏见 2024-10-27 07:33:19

我建议您实施策略模式(http://www.dofactory.com/Patterns/PatternStrategy.aspx

您可以针对不同的计算需求加载不同的策略(算法)。

还有一篇不错的文章http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/22/applying-strategy-pattern-instead-of-using-switch-statements。 ASPX

I would suggest you implement strategy pattern (http://www.dofactory.com/Patterns/PatternStrategy.aspx)

You can load different strategies (algorithms) for different calculations required.

There is a nice post as well http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/22/applying-strategy-pattern-instead-of-using-switch-statements.aspx

倾其所爱 2024-10-27 07:33:19

您可以使用 C# 中的 switch 语句根据来自数据库的记录字段(或标量)的值来执行所需的操作。如果您支持的操作数量较少/有限,那么这是可以的,否则您当然可以使用 reflection 和 MethodInfo 类通过“字符串名称”调用某个类的成员方法。

You can use the switch statement in C# to execute the operation you want depending on the value of your record's field (or scalar) coming from the database. This is OK if you have a small/limited number of supported operations, otherwise of course you could use reflection and the MethodInfo class to invoke a member method by "string name" on a certain class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文