是否有这种模式的名字吗? (C#编译时类型安全与" PARAMS"不同类型的参数) [英] Is there a name for this pattern? (C# compile-time type-safety with "params" args of different types)

查看:139
本文介绍了是否有这种模式的名字吗? (C#编译时类型安全与" PARAMS"不同类型的参数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有这种模式的名称?

Is there a name for this pattern?

让我们假设你想创建一个采用可变数量的参数的方法,每个都必须是一个组固定的类型(以任意顺序或组合),以及一些这些类型的,你无法控制的。一种常见的方法就是让你的方法带Object类型的参数,并在运行时验证类型:

Let's say you want to create a method that takes a variable number of arguments, each of which must be one of a fixed set of types (in any order or combination), and some of those types you have no control over. A common approach would be to have your method take arguments of type Object, and validate the types at runtime:

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");
    }
}



但是,让我们说,像我一样,你'再迷恋编译时类型安全,并希望能够在编译时验证方法的参数类型。这是我想出了一个办法:

However, let's say that, like me, you're obsessed with compile-time type safety, and want to be able to validate your method's argument types at compile time. Here's an approach I came up with:

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); }

}

的隐式转换允许你通过有效的参数类型直接向您的常规,而无需显式铸造或包装他们。如果试图传递一个不可接受的类型的值,误差会在编译时被捕获。

The implicit casts allow you to pass arguments of valid types directly to your routine, without having to explicitly cast or wrap them. If you try to pass a value of an unacceptable type, the error will be caught at compile time.

我相信其他人都用这个办法,所以我想知道是否有这个模式的名称。

I'm sure others have used this approach, so I'm wondering if there's a name for this pattern.

推荐答案

似乎没有要对Interwebs命名模式,而是基于对你的问题的瑞安的评论,我投模式的名称应为可变参数的类型安全

There doesn't seem to be a named pattern on the Interwebs, but based on Ryan's comment to your question, I vote the name of the pattern should be Variadic Typesafety.

一般情况下,我会用很谨慎,但我不评判模式好或坏。许多评论者都取得了良好的分赞成和反对的,这是我们对于其他模式,如工厂服务定位器依赖关系注入的<见EM> MVVM 的等,这是所有关于上下文。因此,这里的那个刺...

Generally, I would use it very sparingly, but I'm not judging the pattern as good or bad. Many of the commenters have made good points pro and con, which we see for other patterns such as Factory, Service Locator, Dependency Injection, MVVM, etc. It's all about context. So here's a stab at that...

上下文

一个变量集的不同对象必须进行处理。

A variable set of disparate objects must be processed.

使用时


  1. 您的方法可以接受可变数目的不同类型的参数不具有一个共同的基本类型。

  2. 您的方法被广泛使用(即在代码中的许多地方和/或者你的框架的用户的一大数目。问题的关键是,该类型安全提供了足够的益处,以保证其使用。

  3. 的参数可以以任何顺序传递,但一组不同类型的是有限的,唯一一套可以接受的方法。

  4. 表现力是你的设计目标,你不想把责任推给用户创建包装或适配器(见的替代的)。

  1. Your method can accept a variable number of arguments of disparate types that don't have a common base type.
  2. Your method is widely used (i.e. in many places in code and/or by a great number of users of your framework. The point being that the type-safety provides enough of a benefit to warrant its use.
  3. The arguments can be passed in any order, yet the set of disparate types is finite and the only set acceptable to the method.
  4. Expressiveness is your design goal and you don't want to put the onus on the user to create wrappers or adapters (see Alternatives).

实施

您已经提供了这一点。

例子


  • 的LINQ to XML(如: 新的XElement(...)

  • 其他助剂,如那些构建SQL参数。

  • 处理器外墙(如那些可以接受不同类型的代表,或从不同的框架指令的对象)来执行命令,而无需建立明确的命令适配器。

替代


  • 适配器的。接受可变数量的某些适配器类型(如适配器和LT的参数; T> 或子类是非一般适配器 ),该方法可以与产生所需的结果的工作。这扩大了一套你的方法可以使用(该类型没有再有限),但如果适配器做正确的事,使处理仍然没有工作丢失。缺点是用户指定的现有和/或创建新的适配器的额外负担,这也许是从意图减损(即增加了礼,弱化本质)。

  • 删除类型安全的。这需要接受一个非常基本类型(例如对象),并把运行时检查。什么知道通过负担被传递给用户,但代码仍表现力。错误不显露自己,直到运行时。

  • 组合的。通过一个单一的对象是人的复合物。这需要预先方法调用建立,但转予回使用上述模式的复合材料的集合中的项目之一。

  • 流利的API 的。更换成一系列具体的调用,每一个种类可以接受的说法的单呼。一个典型的例子就是的StringBuilder

  • Adapter. Accept a variable number of arguments of some adapter type (e.g. Adapter<T> or subclasses of a non-generic Adapter) that the method can work with to produce the desired results. This widens the set your method can use (the types are no-longer finite), but nothing is lost if the adapter does the right thing to enable the processing to still work. The disadvantage is the user has the additional burden of specifying existing and/or creating new adapters, which perhaps detracts from the intent (i.e. adds "ceremony", and weakens "essence").
  • Remove Type Safety. This entails accepting a very base type (e.g. Object) and placing runtime checks. Burden on what to know to pass is passed to the user, but the code is still expressive. Errors don't reveal themselves until runtime.
  • Composite. Pass a single object that is a composite of others. This requires a pre-method-call build up, but devolves back to using one of the above patterns for the items in the composite's collection.
  • Fluent API. Replace the single call with a series of specific calls, one for each type of acceptable argument. A canonical example is StringBuilder.

这篇关于是否有这种模式的名字吗? (C#编译时类型安全与&QUOT; PARAMS&QUOT;不同类型的参数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆