这种模式有名字吗? (C# 编译时类型安全,具有不同类型的“params”参数)

2024-01-02

这种模式有名字吗?

假设您想要创建一个采用可变数量参数的方法,每个参数都必须是一组固定类型(以任何顺序或组合)之一,并且其中一些类型您无法控制。一种常见的方法是让您的方法采用 Object 类型的参数,并在运行时验证类型:

void MyMethod (params object[] args)
{
    foreach (object arg in args)
    {
        if (arg is SomeType)
            DoSomethingWith((SomeType) arg);
        else if (arg is SomeOtherType)
            DoSomethingElseWith((SomeOtherType) arg);
        // ... etc.
        else throw new Exception("bogus arg");
    }
}

但是,假设您像我一样痴迷于编译时类型安全,并且希望能够在编译时验证方法的参数类型。这是我想出的一种方法:

void MyMethod (params MyArg[] args)
{
    // ... etc.
}

struct MyArg
{
    public readonly object TheRealArg;

    private MyArg (object obj) { this.TheRealArg = obj; }

    // For each type (represented below by "GoodType") that you want your 
    // method to accept, define an implicit cast operator as follows:

    static public implicit operator MyArg (GoodType x)
    { return new MyArg(x); }

}

隐式转换允许您将有效类型的参数直接传递到例程,而无需显式转换或包装它们。如果尝试传递不可接受类型的值,则会在编译时捕获错误。

我确信其他人已经使用过这种方法,所以我想知道这种模式是否有一个名称。


互联网上似乎没有命名模式,但基于Ryan https://stackoverflow.com/users/864087/ryan-russell对你的问题的评论,我投票模式的名称应该是Variadic https://en.wikipedia.org/wiki/Variadic_function类型安全.

一般来说,我会非常谨慎地使用它,但我不会判断该模式的好坏。许多评论者都提出了赞成和反对的好观点,我们在其他模式中也看到了这一点,例如Factory, 服务定位器, 依赖注入, MVVM等等。这都是关于上下文的。所以这是一个尝试......

Context

必须处理不同对象的可变集合。

Use When

  1. 您的方法可以接受不同数量的不具有公共基类型的不同类型的参数。
  2. 您的方法被广泛使用(即在代码中的许多地方和/或框架的大量用户)。重点是类型安全性提供了足够的好处来保证其使用。
  3. 参数可以按任何顺序传递,但不同类型的集合是有限的,并且是该方法可接受的唯一集合。
  4. 表现力是您的设计目标,您不想让用户承担创建包装器或适配器的责任(请参阅备择方案).

执行

你已经提供了。

Examples

  • LINQ 到 XML(例如new XElement(...))
  • 其他构建器,例如构建 SQL 参数的构建器。
  • 处理器外观(例如,那些可以接受来自不同框架的不同类型的委托或命令对象的处理器外观)来执行命令,而无需创建显式命令适配器。

备择方案

  • Adapter。接受某种适配器类型的可变数量的参数(例如Adapter<T>或非泛型的子类Adapter)该方法可以用来产生所需的结果。这扩大了您的方法可以使用的集合(类型不再是有限的),但如果适配器执行正确的操作以使处理仍然有效,则不会丢失任何内容。缺点是用户有指定现有和/或创建新适配器的额外负担,这可能会偏离意图(即增加“仪式”,并削弱“本质”)。
  • 删除类型安全。这需要接受一个非常基本的类型(例如Object)并进行运行时检查。需要传递什么信息的负担被传递给用户,但代码仍然具有表现力。错误直到运行时才会显现出来。
  • 合成的。传递由其他对象组合而成的单个对象。这需要方法调用前的构建,但又会返回到对组合集合中的项目使用上述模式之一。
  • 流畅的API。将单个调用替换为一系列特定调用,每个调用对应一种可接受的参数类型。一个典型的例子是StringBuilder.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这种模式有名字吗? (C# 编译时类型安全,具有不同类型的“params”参数) 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • Func 方法参数的首选命名约定是什么?

    我承认这个问题是主观的 但我对社区的观点感兴趣 我有一个缓存类 它采用类型的缓存加载器函数Func
  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 将应用程序从 Microsoft Access 迁移到 VB 或 C#.NET

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new
  • 不同类型的指针可以互相分配吗?

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

随机推荐

  • 如何使用Cloudinary jQuery插件直接从页面上传图像?

    初学者的问题在这里 我正在尝试将照片从网页直接上传到云数 http cloudinary com Here https github com cloudinary cloudinary js是Cloudinary推荐使用的jQuery插件
  • 如何将 Symfony2 操作嵌入到 WordPress 中?

    我已经做了很多研究并尝试过 但我有点困惑 我想在 WordPress 中设置一个网站 这对与我一起工作的另一个人很有帮助 该网站将为我们的产品做广告并提供信息 然后用户可以通过一系列表格进行注册 我想在 Symfony2 中编写这个自定义部
  • 为什么 Akka-Http 仍然使用旧的 Akka-Actor?

    我已将最新的 akka http 添加到我的项目中 但其中包括 akka actor 上非常旧的 2 4 19 版本 因此我还将 akka actor 版本 2 5 4 添加到依赖项中 但是 这会导致以下错误 Detected java l
  • 当您在 ASP.NET 2.0 中使用登录控件时,将值或数据从一个页面传递到另一页面

    我在登录页面中使用 ASP NET 2 0 中提供的登录控件 一旦用户通过数据库身份验证成功 我就会将用户重定向到 home aspx 在这里 我也想将用户的名称传递给 home aspx 以便用户在 home aspx 中看到他 她的名字
  • S4错误:可以定义方法,但泛型函数是隐式的,无法更改

    我正在通过 S4 创建以下方法 name title Expand outputs description Operator outputs of function create return expanded creation expor
  • 我在哪里可以获得 JOGL JAR?

    这可能听起来很愚蠢 但我不知道在哪里可以找到 JOGL JAR 我搜索了他们的网站 http jogamp org jogl www http jogamp org jogl www 并且找不到它 有人可以帮忙吗 谢谢 blargman 看
  • 异步函数javascript没有在后台运行?

    console log 1 console log 2 async function a for let i 0 i lt 1000000000 i for let i 0 i lt 1000000000 i a then gt conso
  • 在MySQL中模拟滞后函数

    time company quote 0000 00 00 00 00 00 GOOGLE 40 2012 07 02 21 28 05 GOOGLE 60 2012 07 02 21 28 51 SAP 60 2012 07 02 21
  • 如何使用搜索参数搜索Html表格数据

    我有一个 HTML 表 我正在其中填充 JSON 数据 我提供了一个搜索字段 它提供了搜索表数据 现在我想做的是 我有一个select由表头名称组成的下拉列表 单击该选项后 我只想搜索该特定列 假设这里我有一个列名称为User Code 因
  • 如何从 Pinterest API 获取搜索源

    我正在寻找以下的搜索源Pinterest移动应用程序API 我可以知道如何获取搜索源吗Pinterest API 自 2019 年起 此功能已被弃用 我认为this https github com cypherpunk99 guipint
  • Smalltalk中new和initialize的区别?

    新手问题 new和initialize有什么区别 确切地 当您发送消息 new时 它不仅创建对象 而且发送消息 initialize 这使您可以自定义对象的初始化 看 Behavior gt gt new Answer a new init
  • 在 Windows 上查找使用端口的进程的 PID

    我的服务在经典启动时崩溃 java rmi server ExportException Listen failed on port 9999 我怎样才能找到杀死它的进程 只需打开命令 shell 并输入 假设您的端口是 123456 ne
  • React-apollo 的动态突变文档

    我需要动态更改我的突变文档 以便能够在单个突变中创建多个项目 所以我有这个功能createOrderName它需要一个整数并能够创建正确的突变文档 例如 createOrderName 2 gets mutation createOrder
  • Ruby 中解析 HTML 文档的方法?

    就像 PHP 中的 DOMDocument 类一样 RUBY 中是否有任何类 即核心 RUBY 可以从 HTML 文档中解析并获取节点元素值 目前还没有内置的 HTML 解析器 但有一些非常好的解析器可用 特别是Nokogiri http
  • 如何使用 CarrierWave 重新组织现有文件夹层次结构?

    我正在尝试使用以下命令在我的 S3 存储桶中移动文件CarrierWave重新组织文件夹结构 我来到一个现有的 Rails 应用程序 其中一个类的所有图像都被上传到一个名为的文件夹中 uploads 这会导致问题 如果两个用户上传具有相同文
  • 使用paint(Graphics p)时删除java中的一行?

    我使用以下函数画了一条线 public void paint Graphics p super paint p p drawLine 600 200 580 250 我想知道有没有办法删除这一行 那么是否可以在main 程序的方法 您可以使
  • 使用 JavaScript 重新排列 ListBox 元素会导致回发时发生事件验证错误

    我创建了一个项目交换器控件 其中包含两个列表框和一些按钮 允许我在两个列表之间交换项目 交换是使用 javascript 完成的 我还在列表中上下移动项目 基本上 当我将项目移动到右侧的列表框时 我将元素的数据键 GUID 存储在隐藏字段中
  • 有没有办法加快 numpy.where 的循环速度?

    想象一下 您有一个分割图 其中每个对象都由唯一索引标识 例如看起来与此类似 对于每个对象 我想保存它覆盖的像素 但我只能提出标准for循环至今 不幸的是 对于包含数千个单独对象的较大图像 这结果非常慢 至少对于我的真实数据来说是这样 我能以
  • 如何在 Blackberry 中以编程方式发送短信

    如何在黑莓手机中以编程方式发送短信 我在某处读到 我需要服务器端和客户端代码来发送短信 这是真的吗 为了将消息从一个设备发送到另一个设备或从模拟器发送到设备 我真的需要服务器端和客户端代码吗 我在客户端的某个地方找到了这段代码 但我没有得到
  • 这种模式有名字吗? (C# 编译时类型安全,具有不同类型的“params”参数)

    这种模式有名字吗 假设您想要创建一个采用可变数量参数的方法 每个参数都必须是一组固定类型 以任何顺序或组合 之一 并且其中一些类型您无法控制 一种常见的方法是让您的方法采用 Object 类型的参数 并在运行时验证类型 void MyMet