gpt4 book ai didi

c# - 使用 .NET 泛型改进具有可变参数的方法

转载 作者:太空狗 更新时间:2023-10-30 00:09:08 24 4
gpt4 key购买 nike

我有很多函数当前重载以对 intstring 进行操作:

bool foo(int);
bool foo(string);
bool bar(int);
bool bar(string);
void baz(int p);
void baz(string p);

然后我有很多函数采用 intstring 的 1、2、3 或 4 个参数,它们调用上述函数:

void g(int p1)    { if(foo(p1)) baz(p1); }
void g(string p1) { if(foo(p1)) baz(p1); }

void g(int p2, int p2) { if(foo(p1)) baz(p1); if(bar(p2)) baz(p2); }
void g(int p2, string p2) { if(foo(p1)) baz(p1); if(bar(p2)) baz(p2); }
void g(string p2, int p2) { if(foo(p1)) baz(p1); if(bar(p2)) baz(p2); }
void g(string p2, string p2) { if(foo(p1)) baz(p1); if(bar(p2)) baz(p2); }

// etc.

注意:g()族的实现只是一个例子

可能随时引入比当前 intstring 更多的类型。对于参数超过 4 个的函数也是如此。目前相同函数的数量几乎无法管理。在任一维度上再添加一个变体,组合爆炸将如此巨大,它可能会摧毁应用程序。

在 C++ 中,我会将 g() 模板化并完成。

我知道 .NET 泛型是不同的。我已经和他们战斗了两个小时,现在试图想出一个不涉及复制和粘贴代码的解决方案,但无济于事。

C# 泛型不会要求我为采用三种类型中的任何一种的五个参数的函数族键入相同的代码吗?

我错过了什么?

编辑: 这些函数用于解析一堆参数(目前是 intstring)来自某些来源。想象一下 bar()baz() 能够读取 intstring,而 g() 系列指定要解析的参数的类型和数量(隐含地,通过它们的参数类型)。

最佳答案

考虑在这种情况下使用继承。我假设 foo , barbaz是类型固有的(在您的情况下为 int 或 string)。如果这不是真的,请更正或评论此答案。

using System;

namespace ConsoleApplication3
{
abstract class Param
{
public abstract bool Foo();
public abstract bool Bar();
public abstract void Baz();

public static IntParam Create(int value)
{
return new IntParam(value);
}

public static StringParam Create(string value)
{
return new StringParam(value);
}
}

abstract class Param<T> : Param {
private T value;

protected Param() { }

protected Param(T value) { this.value = value; }

public T Value {
get { return this.value; }
set { this.value = value; }
}
}

class IntParam : Param<int>
{
public IntParam() { }
public IntParam(int value) : base(value) { }

public override bool Foo() { return true; }
public override bool Bar() { return true; }

public override void Baz()
{
Console.WriteLine("int param value is " + this.Value);
}
}

class StringParam : Param<string>
{
public StringParam() { }
public StringParam(string value) : base(value) { }

public override bool Foo() { return true; }
public override bool Bar() { return true; }

public override void Baz()
{
Console.WriteLine("String param value is " + this.Value);
}
}

class Program
{
static void g(Param p1)
{
if (p1.Foo()) { p1.Baz(); }
}

static void g(Param p1, Param p2)
{
if (p1.Foo()) { p1.Baz(); }
if (p2.Bar()) { p2.Baz(); }
}

static void Main(string[] args)
{
Param p1 = Param.Create(12);
Param p2 = Param.Create("viva");

g(p1);
g(p2);
g(p1, p1);
g(p1, p2);
g(p2, p1);
g(p2, p2);

Console.ReadKey();
}
}
}

这将输出:

int param value is 12
String param value is viva
int param value is 12
int param value is 12
int param value is 12
String param value is viva
String param value is viva
int param value is 12
String param value is viva
String param value is viva

对于新的受支持类型,您:

  1. 创建一个支持类型并扩展Param<T> 的新类;
  2. 实现Foo , BarBaz对于那个新类型;
  3. 创建一个新的 g具有另一个参数的方法(只有一个)。

特别针对 3) 这将大大减少方法的爆炸。现在你写一个 g任何给定数量的参数的方法。对于以前的设计,您必须为 n 编写参数,2^n方法(n = 1 -> 2 种方法,n = 2 -> 4 种方法,n = 3 -> 8 种方法,..)。

关于c# - 使用 .NET 泛型改进具有可变参数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3071450/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com