除了对象实例之外,我可以使用什么可传递的值来访问多个函数

本文关键字:可传递 访问 函数 什么 实例 对象 可以使 我可以 | 更新日期: 2023-09-27 18:03:13

我正在学习c#,我正在寻找一个问题的解决方案,这个问题可能是由糟糕的体系结构引起的,并且不会影响到现实生活中的程序。

我想通过"东西"(不一定是一个类),拥有多种功能,不需要实例化,例如,我想上课的时间和任务在一本字典,所以,例如,在12点我想让类的"午餐",但这午餐可能依赖于其他变量,所以我有一个dict条目检查{12 LunchTask}, LunchTask子类/实现/派生的"任务"所以我们可以安全地把它和类似SomeTask打电话。首先,SomeTask。暂停,SomeTask.Stop .

我虽然使用字典(int,System.Type),但无法让它工作,我也尝试过静态,但它们不能被子类化,据我所知,委托是针对单个函数的。我只是想在字典中传递一些东西,它的函数可以直接访问而不需要实例化。我知道有一个解决方案是可行的,但我发现非常不优雅,那就是用一个包含所有不同任务实例的静态类。

我不知道有什么更好的方法来实现这样一个基本的功能,也许我做的每件事都大错特错。所以如果你们能给我指个方向我会很感激的。提前谢谢你。

下面是一些(伪c#)代码:
public abstract class Task {
    public abstract void ExecuteTask ();
    public virtual void PauseTask() {Console.WriteLine ("Task Paused")}
    public virtual void StopTask() {Console.WriteLine ("Task Stopped")}
}
public class Lunch : Task {
    public override void ExecuteTask ()
    {
        Console.WriteLine ("Lunch Task Started");
    }
}
//the following is gonna be instantiated
public class Human {
    Dictionary<int, Something> attributions =  new Dictionary<int, Something>(){{12, Lunch}};
    void ToBeCalledEveryHour () {
        int hour = someHour();
        if (attributions.ContainsKey(hour))
            attributions[hour].ExecuteTask();
    }
}

除了对象实例之外,我可以使用什么可传递的值来访问多个函数

根据您的情况,您可以使用对象池模式或工厂模式。

在对象池模式的情况下,你可以有一个Map,其中键应该是唯一标识对象的字符串,例如它可以是类名,值可以是对应的对象。

:

public abstract class Task {
public abstract void ExecuteTask ();
public virtual void PauseTask() {Console.WriteLine ("Task Paused")}
public virtual void StopTask() {Console.WriteLine ("Task Stopped")}
}
public class Lunch : Task {
   public override void ExecuteTask ()
   {
     Console.WriteLine ("Lunch Task Started");
   }
}
public class ObjectCollection{
    Dictionary<string,Task> objectStringMapper= new Dictionary<string,string>();
    Dictionary<string,Task> objectTimeMapper= new Dictionary<string,string>();
    public ObjectCollection(){
        objectMapper.Add("Lunch",new LunchTask());
        objectTimeMapper.Add(12,new LunchTask());        
    }
    public Task getObject(string objId){
        return objectMapper.get(objId);
    }
    public Task getObject(int time){
        return objectTimeMapper.get(time);
    } 
 }
public class Human {
    ObjetCollection objectsFactory = new ObjectCollection();
    void ToBeCalledEveryHour () {
        int hour = someHour();
        if (attributions.ContainsKey(hour))
            objectsFactory.getObject(hour).ExecuteTask();
      }
}

或者你可以选择工厂模式,在这种模式下,你可以有一个类来创建使用反射或切换情况的对象。

注意:由于我是Java开发人员和c#新手,您可能会发现一些语法错误。

如果您的方法的参数总是相同的,这是一个足够简单的事情。然而,如果它们是不同的,这将是非常困难的

我会说,我看不出这与仅仅在Dispatcher外部实例化你想要的对象并在内部调用它的方法相比有多大的优势。

但这里有一个非常基本的例子,你正在努力实现(编辑响应您发布的代码):

//Method Call:
Dictionary<int, System.Type> attributions = new Dictionary<int, System.Type>(){{12, typeof[Lunch]}};
Dispatcher(attributions);
//Dispatcher
public void Dispatcher(IDictionary<int, System.Type> dictionary) {
    int hour = SomeHour()
    // Instantiate object
    var obj = Activator.CreateInstance(attributions[hour]);
    //Build args
    var args = new object[]{
        new object(),
    };
    // Invoke method
    type.InvokeMember("ExecuteTask", System.Reflection.BindingFlags.Public, null, obj, args);
}

您可以使用下面的代码来存储每个函数具有相同签名的函数字典。

然后可以传递对这样一个字典的引用。还可以将对静态Compute方法的引用传递给任何接受Func<ArithmeticFunction、int、int、int> 的方法。
internal enum ArithmeticFunction
{
   Add,
   Subtract,
   Multiply,
   Divide,
   Min,
   Max,
}
internal static class FunctionMap
{
   private static readonly Dictionary<ArithmeticFunction, Func<int, int, int>> s_map;
   static FunctionMap()
   {
      s_map = new Dictionary<ArithmeticFunction, Func<int, int, int>>();
      s_map[ArithmeticFunction.Add] = (x, y) => x + y;
      s_map[ArithmeticFunction.Subtract] = (x, y) => x - y;
      s_map[ArithmeticFunction.Multiply] = (x, y) => x * y;
      s_map[ArithmeticFunction.Divide] = (x, y) => x / y;
      s_map[ArithmeticFunction.Min] = System.Math.Min;
      s_map[ArithmeticFunction.Max] = System.Math.Max;
   }
   //Don't allow callers access to the core map.  Return them a copy instead.
   internal static Dictionary<ArithmeticFunction, Func<int, int, int>> GetCopy()
   {
      return new Dictionary<ArithmeticFunction, Func<int, int, int>>(s_map); 
   }
   internal static int Compute(ArithmeticFunction op, int x, int y)
   {
      return s_map[op](x, y);
   }
}
static void Main(string[] args)
{
   System.Diagnostics.Trace.WriteLine("Example 1:");
   System.Diagnostics.Trace.WriteLine(FunctionMap.Compute(ArithmeticFunction.Add, 12, 4));
   System.Diagnostics.Trace.WriteLine(FunctionMap.Compute(ArithmeticFunction.Subtract, 12, 4));
   System.Diagnostics.Trace.WriteLine(FunctionMap.Compute(ArithmeticFunction.Multiply, 12, 4));
   System.Diagnostics.Trace.WriteLine(FunctionMap.Compute(ArithmeticFunction.Divide, 12, 4));
   System.Diagnostics.Trace.WriteLine(FunctionMap.Compute(ArithmeticFunction.Min, 12, 4));
   System.Diagnostics.Trace.WriteLine(FunctionMap.Compute(ArithmeticFunction.Max, 12, 4));
   var safeCopy = FunctionMap.GetCopy();
   System.Diagnostics.Trace.WriteLine("Example 2:");
   System.Diagnostics.Trace.WriteLine(safeCopy[ArithmeticFunction.Add](72, 9));
   System.Diagnostics.Trace.WriteLine(safeCopy[ArithmeticFunction.Subtract](72, 9));
   System.Diagnostics.Trace.WriteLine(safeCopy[ArithmeticFunction.Multiply](72, 9));
   System.Diagnostics.Trace.WriteLine(safeCopy[ArithmeticFunction.Divide](72, 9));
   System.Diagnostics.Trace.WriteLine(safeCopy[ArithmeticFunction.Min](72, 9));
   System.Diagnostics.Trace.WriteLine(safeCopy[ArithmeticFunction.Max](72, 9));

输出如下:

Example 1:
16
8
48
3
4
12
Example 2:
81
63
648
8
9
72