【发布时间】:2015-07-17 03:20:28
【问题描述】:
这种模式有名字吗?
假设您要创建一个方法,该方法采用可变数量的参数,每个参数必须是一组固定类型中的一个(以任何顺序或组合),其中一些类型您无法控制。一种常见的方法是让您的方法采用 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); }
}
隐式转换允许您将有效类型的参数直接传递给您的例程,而无需显式转换或包装它们。如果您尝试传递不可接受类型的值,则会在编译时捕获错误。
我相信其他人已经使用过这种方法,所以我想知道这种模式是否有名称。
【问题讨论】:
-
我可能遗漏了一些东西,但我没有看到任何规律。
-
你知道,你可以让“必需类型”实现一个通用接口,然后取一个
params IWhatever[] args。 -
@Etienne 你不能将接口改装成
string之类的东西...... -
@Ed 我认为如果您必须提出一个不寻常的解决方案,那就是过度工程,因为这通常意味着您最初解决问题的方式是错误的。更简单的解决方案是不需要使用类型开关的可变参数函数。
-
你知道这让我想起了什么吗? php。即使 PHP 是动态类型的,而 C# 是静态类型的。
标签: c# params type-safety