使用策略模式在 C# 上实现类似多参数 C++ 模板的行为

2023-11-22

我正在尝试使用 C# 泛型和基于策略模式的 C++ 模板来实现这个答案

这是该模式的示例:

interface ISomePolicy<T,U>
{
    void _doSomething(U u);
}


class MyClass<T,U>:
     ISomePolicy<int, double>,
     ISomePolicy<int, int>
    {

    internal T myElement {get;set;}

    public MyClass(T Element) {
        myElement = Element;
    }

    void ISomePolicy<int, double>._doSomething(double u)
    {
        Console.WriteLine("this is int, double");
    }

    void ISomePolicy<int, int>._doSomething(int u)
    {
        Console.WriteLine("this is int, int");
    }

    }

static class MyClassExtension
{

    //What I want to do
    public static void doSomething<P, T, U>(this P oTh, U u) where P : MyClass<T, U>, ISomePolicy<T, U>
    {
        oTh._doSomething(u);
    }

}

我的预期行为是这样的:

  MyClass<int, double> oClass = new MyClass<int, double>(3);

  oClass.doSomething(0.5); //This works
  oClass.doSomething(1);   //This works

  oClass.doSomething("This should fail"); //Breaks at compile time           

  MyClass<string, double> oClass1 = new MyClass<string, double>("sadfsd"); //Not implemented, wasn't able to prevent the construction.

  oClass1.doSomething(0.4); //Breaks at compile time

但到目前为止我无法让 .net 接受参数少于参数的通用扩展

我可以显式调用该接口,这是可怕的冗长,违背了这一切的目的。

oClass.doSomething < MyClass<int, double>,int,double>(0.5);

我想用包装器来解决这个问题:

static class MyClassExtension{
    private static void wrappedDoSomething<P, T, U>(this P oTh, U u) 
    where P : MyClass<T, U>, ISomePolicy<T, U>
    {
        oTh._doSomething(u);
    }

    public static void doSomething<T, U>(this MyClass<T, U> oTh, U u)

    {
        oTh.wrappedDoSomething<MyClass<T, U>, T, U>(u);
    }
}

但包装器无法解析包装函数的两种类型,失败并显示:

错误 1 ​​类型“MyClass”不能用作类型参数“P” 在泛型类型或方法中 'MyClassExtension.wrappedDoSomething(P, U)'。没有 从 'MyClass' 到的隐式引用转换 “我有一些政策”

任何解决参数问题或重新设计所有这些的见解都值得赞赏。


对于上下文,这将用于包装 I/O 转换器。T在我的例子中是目标 I/O 格式,并且U我的框架使用的数据的对象表示。

我知道这可以通过委托或接口轻松实现,但目标是框架用户可以轻松实例化所需的翻译,并且如果实现不存在,则可以轻松地将其添加到公共接口中。


编辑:从另一个通用方法/类内部解析通用方法似乎都不适用于单声道。


通常,策略不应包含数据。例如,

interface ISomePolicy<T, U>
{
    void _doSomething(T t, U u);
}

struct SomePolicyImplementation :
    ISomePolicy<int, double>,
    ISomePolicy<int, int>,
    ISomePolicy<double, double>
{
    void ISomePolicy<int, int>._doSomething(int t, int u)
        => Console.WriteLine("this is int, int");

    void ISomePolicy<int, double>._doSomething(int t, double u)
        => Console.WriteLine("this is int, double");

    void ISomePolicy<double, double>._doSomething(double t, double u)
        => Console.WriteLine("this is double, double");
}

static class SomePolicyExtension
{
    public static void doSomething<P, T, U>(this P policy, T t, U u)
        where P : struct, ISomePolicy<T, U>
        => policy._doSomething(t, u);
}

如果您想结合策略和数据,那么您可以考虑不同的接口

interface IEmbeddedPolicy<U>
{
    void _doSomething(U u);
}

class MyClass<T> :
    IEmbeddedPolicy<double>,
    IEmbeddedPolicy<int>
{
    public T Value { get; }

    public MyClass(T value) { this.Value = value; }

    void IEmbeddedPolicy<int>._doSomething(int u)
        => Console.WriteLine("this is T, int");

    void IEmbeddedPolicy<double>._doSomething(double u)
        => Console.WriteLine("this is T, double");
}

static class EmbeddedPolicyExtension
{
    public static void doSomething<E, U>(this E embedded, U u)
        where E : IEmbeddedPolicy<U>
        => embedded._doSomething(u);
}

或者这两个概念的组合

class MySuperClass<P, T>:
    IEmbeddedPolicy<double>,
    IEmbeddedPolicy<int>
    where P: struct, ISomePolicy<T, double>, ISomePolicy<T, int>
{
    public T Value { get; }

    public MySuperClass(T value) { this.Value = value; }

    void IEmbeddedPolicy<int>._doSomething(int u)
        => new P()._doSomething(this.Value, u);

    void IEmbeddedPolicy<double>._doSomething(double u)
        => new P()._doSomething(this.Value, u);
}

Usage:

// independent policy
var policy = new SomePolicyImplementation();

policy.doSomething(5, 6);
policy.doSomething(5, 6.7);
policy.doSomething(5.3, 6.7);

// embedded policy
var my = new MyClass<int>(54);
my.doSomething(5);
my.doSomething(89.7);

// combination
var x = new MySuperClass<SomePolicyImplementation, int>(53);
x.doSomething(9);
x.doSomething(18.3);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用策略模式在 C# 上实现类似多参数 C++ 模板的行为 的相关文章

  • 在 RESTful Web 服务中实现注销

    我正在开发一个需要注销服务的移动应用程序 登录服务是通过数据库验证来完成的 现在我陷入了注销状态 退一步 您没有提供有关如何在应用程序中执行身份验证的详细信息 并且很难猜测您在做什么 但是 需要注意的是 在 REST 应用程序中 不能有会话
  • 仅当显式选择行时才关闭 ui-bootstrap typeahead

    我创建了这个jsBin http jsbin com livuqafe 2 edit来证明我遇到的问题 如果您转到此处 请尝试输入 五 并继续 你的自然反应是输入 五 然后按 Tab 如果你想要 五百 你可以向下箭头一次 但是 在这种情况下
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo
  • 没有输入的 jQuery 日期选择器

    我有一个相当复杂的网络应用程序 我想向其中添加一些日期选择 UI 我遇到的问题是我无法从文档中弄清楚如何真正控制日期选择器的出现方式和时间 不涉及任何表单元素 不 我不会添加秘密表单字段 因此简单的开箱即用方法根本行不通 我希望有人可以提供
  • PrimeFaces 对话框参考父级

    我有一个 xhtml 页面 显示带有条目的数据表 我还有一个用于插入新条目的按钮 该按钮显示一个包含表单的对话框 插入表格用作
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 将第三个表链接到多对多关联中的桥接表

    设计这个数据库的正确方法是什么 这是我设置表格的方式 我在名为 教师 的表和名为 仪器 的表之间存在多对多关系 然后我有一个连接两者的桥接表 我想将另一个表与 BRIDGE 表关联起来 意思是乐器 老师的组合 该表有 3 行 指定老师可以教
  • Amazon RDS for SQL Server 是否支持 SSIS?

    从谷歌搜索中读到一些相互矛盾的答案 不确定答案是是 否还是可能 我觉得读的时候已经很清楚了this http docs aws amazon com AmazonRDS latest UserGuide CHAP SQLServer htm
  • 一种无需 JavaScript 即可在 PHP 中确定浏览器宽度的方法?

    首先有吗 或者我必须使用javascript 我希望能够更改使用的 CSS 因此 frex 我可以为移动设备或其他设备加载较小的字体 不幸的是 仅使用 PHP 无法检测用户分辨率 如果您使用 Javascript 则可以在 cookie 中
  • 如何在 Angular 4 中翻译 mat-paginator?

    你知道如何在 Angular 中翻译 每页项目 吗mat paginator标签 这mat paginator是材料设计中的一个元素 您可以使用MatPaginatorIntl为了这 威尔 豪厄尔制作 https github com an
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 使用velocity.js制作可拖动元素的动画

    我正在使用velocity js 为用户拖动的可拖动 SVG 元素设置动画 然而 velocity js 将先前的 mousemove 坐标排队并通过所有后续的 mousemove 坐标进行动画处理 我想要的是velocity js 不要对
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使
  • 如何在 OSX 上安装 LaTeX .sty 文件?

    我设置了一个 LaTeX 项目 tex documents some file tex support todonotes sty where some file tex uses todonotes usepackage colorinl
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前
  • Android 材料芯片组件崩溃应用程序。无法膨胀 xml

    Tried Chip来自两个支持库的组件 com google android support design 28 0 0 rc01和材料 com google android material material 1 0 0 rc01 堆栈
  • 禁用允许文本选择的

    残疾人可以吗
  • PyAudio ErrNo 输入溢出 -9981

    我遇到了与用户相同的错误 Python 使用 Pyaudio 以 16000Hz 录制音频时出错 https stackoverflow com questions 12994981 python error audio recording
  • 探查器模板可以迁移到较新版本的 SQL Profiler 吗?

    是否可以将 Profiler 模板迁移到较新版本的 SQL Server 就我而言 我想将 SQL 2008 模板带到 2012 年 我尝试过 1 直接文件复制和 2 导出 导入 在这两种情况下 旧模板都会运行 但无法修改 修改后会出现以下

随机推荐

  • 谷歌地图信息窗口位于右侧

    如何在左侧显示带有箭头的信息窗口 而不是在底部 屏幕截图示例在这里 已经有一段时间了 也许您确实对这个话题产生了兴趣 但我想说 无需使用任何第三方工具就可以 只需添加pixelOffset to the infowindow像这样 var
  • 同时按下多个按钮

    在我的 WP 7 1 应用程序中 我有一个包含多个按钮的页面 我注意到 当按下任一按钮时 无法按下其他按钮 我怎样才能克服这个问题 我需要能够允许用户同时按下多个按钮 不幸的是 您无法同时处理多个按钮点击 不过 有一种方法可以解决这个问题
  • 如何向 HTML5 Canvas 添加撤消功能?

    我有一个用 HTML5 和 Javascript 完成的草图应用程序 我想知道如何创建一个撤消按钮 这样您就可以撤消您最后绘制的内容 任何想法 您必须将所有修改存储在数据结构中 然后如果用户想要的话可 以删除最新的修改undo它 然后 您再
  • 带有基于文件的电子邮件后端服务器的 Django 测试框架

    我在Django框架中制定了测试用例 使用案例 我正在使用 API 通过向用户发送电子邮件来注册用户 当他们单击电子邮件中提供的链接时 他们的帐户就会被激活 在我的 settings py 中我使用 EMAIL FILE PATH djan
  • 将图标与 JCheckBox 一起使用

    我有一个 swing 应用程序 我想在其中使用带有图标的 JCheckbox 我构建的图标如下 JCheckBox unsubmit new JCheckBox Unsubmit applet undo 当我这样做时 标签和图标出现在我的
  • Rails 使所有路由默认格式为::json

    您可以将所有路由默认为json 我有以下 api 范围 但我想知道您是否可以对全局范围执行相同的操作 scope api defaults format json do get search query location gt search
  • Hive - LIKE 运算符

    我不知道如何处理这个问题 这是我的数据 Table1 Table2 BRAND PRODUCT SOLD Sony Sony ABCD 1233 Apple Sony adv 1233 Google Sony aaaa 1233 IBM A
  • 角度 2 贝宝

    我正在使用 Angular 2 和 Firebase 建立一个新的电子商务项目 我的问题是如何集成贝宝按钮 当客户点击它时 他们将被重定向到贝宝并付款 然后重定向回我的网站 目前 我设法让他们回来 要么按照这个 github 存储库中的指示
  • gnuplot 多条线,X 轴上有时间

    我已经查看了问题 但仍然无法正常工作 我的数据集是这样的 date cpu mem 23 00 39 21 9 2 1 23 00 44 21 8 2 1 23 00 49 21 8 2 1 23 00 54 21 8 2 1 23 00
  • 虚拟函数的Vtable如何工作

    我对虚拟表有一个小疑问 每当编译器遇到类中的虚拟函数时 它都会创建Vtable并将虚拟函数地址放在那里 对于其他继承的类 也会发生类似的情况 它是否在每个类中创建一个指向每个 Vtable 的新指针 如果不是 当创建派生类的新实例并将其分配
  • 我可以使用IdUDPClient发送M-SEARCH请求吗?

    我的网络中几乎没有 uPNP 设备 我正在尝试向网络发送 M SEARCH 请求 并希望收到一些响应 这就是我正在尝试的 var sIP sOut string iPort Word S TStringBuilder begin S TSt
  • 在 Bootstrap 中打开放大图像模式

    我如何open enlarge使用 jquery js 的模式中的图像和不是数据属性 每当用户将图像插入内容编辑器时 我都需要它可单击以使用 js 在模式中展开 因此我不能依赖用户输入他们不知道如何使用的数据属性 我试过 a href my
  • 解析 EDGAR 文件

    我想使用 python2 7 删除 EDGAR 文件中非文档文本的任何内容 可在线获取 txt 文件 这些文件的示例如下 Example EDGAR 从该文件的第 48 页开始提供其文档类型定义 DTD 我的程序的第一部分将 txt 文件从
  • R 中计算 R2(R 平方)的函数

    我有一个包含观察数据和建模数据的数据框 我想计算 R2 值 我期望有一个可以调用的函数 但找不到 我知道我可以自己编写并应用它 但我是否遗漏了一些明显的东西 我想要类似的东西 obs lt 1 5 mod lt c 0 8 2 4 2 3
  • ALSA:防止扬声器欠载的方法

    我正在非交错模式下播放单通道音频 当我将音频数据写入扬声器时 我遇到了问题 ALSA lib pcm c 7339 snd pcm recover underrun occurred 我是这样写的 printf d snd pcm avai
  • 使用存储过程的 Azure documentdb 批量插入

    您好 我正在使用 16 个集合插入大约 3 400 万个 json 对象 每个对象 5 10k 我正在使用存储过程来插入这些文档 我有 22 个容量单位 function bulkImport docs var collection get
  • 平台设备从何处获取名称

    我正在阅读关于围绕总线 设备和驱动程序构建的 Linux 设备模型 我能够了解一些有关设备和驱动程序匹配如何发生的信息 但不清楚总线在这里的作用 总线如何与设备匹配 我对平台设备从何而来还有一个疑问 平台总线只是将每个设备的名称与每个驱动程
  • CompilationRelaxations.NoStringInterning 实际上是如何工作的?

    我在演示 NoStringInterning 时遇到问题 assembly System Runtime CompilerServices CompilationRelaxations System Runtime CompilerServ
  • LINQ 中的*右*外连接

    可以肯定地说 LINQ 中不存在右外连接这样的东西吗 我知道要有效地创建一个 您只需交换左外连接中的表即可 但是您可以将 DefaultIfEmpty 方法应用于等值联接左侧的表以使其成为右外联接吗 经过广泛查找 我找不到任何涉及右外连接的
  • 使用策略模式在 C# 上实现类似多参数 C++ 模板的行为

    我正在尝试使用 C 泛型和基于策略模式的 C 模板来实现这个答案 这是该模式的示例 interface ISomePolicy