双重调度和替代方案

2023-12-31

我正在努力寻找更好的方法来处理一些成长if构造来处理不同类型的类。这些类最终是不同值类型(int、DateTime 等)的包装器,并带有一些附加状态信息。因此,这些类之间的主要区别在于它们包含的数据类型。虽然它们实现了泛型接口,但它们也需要保存在同类集合中,因此它们也实现了非泛型接口。类实例根据它们所表示的数据类型进行处理,并且它们的传播基于此继续或不继续。

虽然这不一定是 .NET 或 C# 问题,但我的代码是用 C# 编写的。

示例类:

interface ITimedValue {
 TimeSpan TimeStamp { get; }
}

interface ITimedValue<T> : ITimedValue {
 T Value { get; }
}

class NumericValue : ITimedValue<float> {
 public TimeSpan TimeStamp { get; private set; }
 public float Value { get; private set; }
}

class DateTimeValue : ITimedValue<DateTime> {
 public TimeSpan TimeStamp { get; private set; }
 public DateTime Value { get; private set; }
}

class NumericEvaluator {
 public void Evaluate(IEnumerable<ITimedValue> values) ...
}

我想出了两个选择:

双重派遣

我最近了解了访问者模式及其使用双重调度来处理这种情况。这很有吸引力,因为它不会传播不需要的数据(如果我们只想处理 int,我们可以以与 DateTime 不同的方式处理它)。此外,如何处理不同类型的行为将仅限于处理调度的单个类。但是,如果/当必须支持新的值类型时,则需要进行相当多的维护。

联合级

包含每个支持的值类型的属性的类可能是每个类存储的内容。对值的任何操作都会影响相应的组件。与双分派策略相比,这不太复杂,维护也更少,但这意味着每条数据都将不必要地一直传播,因为您不能再按照“我不对该数据类型进行操作”的方式进行区分”。但是,如果/当需要支持新类型时,它们只需要进入此类(加上需要创建以支持新数据类型的任何其他类)。

class UnionData {
 public int NumericValue;
 public DateTime DateTimeValue;
}

有更好的选择吗?这两个选项中是否有一些我不认为应该做的事情?


方法 1,使用动态进行双重调度(归功于http://blogs.msdn.com/b/curth/archive/2008/11/15/c-dynamic-and-multiple-dispatch.aspx http://blogs.msdn.com/b/curth/archive/2008/11/15/c-dynamic-and-multiple-dispatch.aspx)。 基本上你可以像这样简化你的访客模式:

class Evaluator {
 public void Evaluate(IEnumerable<ITimedValue> values) {
    foreach(var v in values)
    {
        Eval((dynamic)(v));
    }
 }

 private void Eval(DateTimeValue d) {
    Console.WriteLine(d.Value.ToString() + " is a datetime");
 }

 private void Eval(NumericValue f) {
    Console.WriteLine(f.Value.ToString() + " is a float");
 }

}

使用示例:

var l = new List<ITimedValue>(){
    new NumericValue(){Value= 5.1F}, 
    new DateTimeValue() {Value= DateTime.Now}};

new Evaluator()
    .Evaluate(l);
       // output:
       // 5,1 is a float
       // 29/02/2012 19:15:16 is a datetime

方法 2 将使用 @Juliet 提议的 C# 中的 Union 类型here https://stackoverflow.com/questions/3151702/discriminated-union-in-c-sharp(替代实施here http://pastebin.com/EEdvVh2R)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

双重调度和替代方案 的相关文章

  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • *.tlb 文件在运行时使用过吗?

    我正在开发一个通过 COM 互操作公开一些 NET API 的产品 作为构建的一部分 我们为所有此类程序集生成 tlb 文件 并将它们作为单独 SDK 包的一部分提供 我们的客户可以在我们的产品之上安装 SDK 并创建使用我们的 COM A
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐