繁体   English   中英

C#多个类似的过载问题

[英]C# Multiple similar Overload problem

情境

为了实例化基类的两个不同的派生对象,我需要以下两个重载。

问题

编译器对此代码有问题,因为方法是模棱两可的-都以两个字符串作为参数。

如何解决此问题,以便以下代码可以编译?

    public RateInstrument(string ric, string tenor)
    {
        Ric = ric;
        Tenor = tenor;
    }

    public RateInstrument(string ric, string date)
    {
        Ric = ric;
        Date = ConvDate(date);
    }

更改第二个以保留日期。 它的权利,也是它的权利。

(我认为将日期作为字符串接受确实很有意义,并且“ ric”在您的域中表示某些含义。这肯定是一个足够普遍的问题。)

您不能这样做,因为这两个构造函数具有相同的签名,但是一个不错的解决方法是使用静态工厂方法:

private static RateInstrument(string ric, string tenor, string date)
{
    ...
}

public static RateInstrument FromRicAndTenor(string ric, string tenor)
{
    return new RateInstrument(ric, tenor, null);
}

public static RateInstrument FromRicAndDate(string ric, string date)
{
    return new RateInstrument(ric, null, date);
}

静态构造方法的优点:

  • 并不总是必须返回一个新实例(它可以应用缓冲池等)
  • 如果确实有用,则可以返回null
  • 可以比构造函数更容易地在构造前后进行有用的工作

缺点:

  • 当您习惯称呼“新”时看起来很奇怪
  • 继承会变得更加棘手(对于非嵌套的派生类型,您至少必须使构造函数受到保护)

(当然,与实际工厂类型上的实例方法相比,这两种方法都缺乏可注入性。)

为什么不简单地使用带有3个参数的构造函数?

public RateInstrument(string ric, string tenor, string date)
{
    Ric = ric;
    if (!string.IsNullOrEmpty(tenor))
    {
            Tenor = tenor;
    }

    if (!string.IsNullOrEmpty(date))
    {
        Date = ConvDate(date);
    }
}

具有两个不同的功能:

RateInstrumentFromDate(blah,date)

RateInstrumentFromTenor(blah,男高音)

方法签名(包括构造函数)不受参数名称的影响。 您必须更改其中一个构造函数,也许是:

    public RateInstrument(string ric, string tenor) 
{ 
    Ric = ric; 
    Tenor = tenor; 
} 

public RateInstrument(string ric, TypeOfDate date) 
{ 
    Ric = ric; 
    Date = date; 
} 

您需要为这两个构造函数提供不同的签名,目前它们都是

foo(string, string);

否则,您(更不用说编译器)将如何知道要调用的方法?

您也可以将它们放置在不同的类上,或者可以更改传递给第二个构造函数的类型,例如,以下两种方法都可以作为第二种方法:

public RateInstrument(string ric, string tenor, string date)
public RateInstrument(string ric, DateTime date)

如果这两种方法都不适合您的情况(例如,由于tenordate互斥,则不行),则应重新考虑类的设计,以及是否应在不同的类中处理第二种情况。

我经常使用的另一种选择是将诸如日期之类的设置延迟到构造函数之后-再次取决于类的设计。

创建两个静态方法,这些方法将为您创建对象:

static RateInstrument NewRateInstrumentByTenor(string ric, string tenor) {
   return new RateInstrument {
      Ric = ric,
      Tenor = tenor
   }
}
static RateInstrument NewRateInstrumentByDate(string ric, string date) {
   return new RateInstrument {
      Ric = ric,
      Date = ConvDate(date)
   }
}

这里有一些可能的选择。 没有看到更多背景信息,我无法真正说出哪个更好,但这是其中的一些。

  1. 将date参数从字符串更改为适当的Date对象,以区分两个签名。

  2. 两者使用相同的构造函数,并沿DateTime.TryParse使用类似的东西来确定第二个参数是日期还是男高音。

  3. 使用工厂方法而不是构造函数,以便可以使用不同的名称。

想法1和3假定调用代码了解您要创建的对象类型。 想法2允许类保持通用性并自行决定。

在这个问题上我只赚2美分。

您不能有两个签名相同的方法。 签名包括:

  • 方法名称
  • 参数数量
  • 参数的数据类型和顺序
  • 参数修饰符

注意:返回类型不是签名的一部分。 同样,重要的是参数的类型顺序 ,而不是其名称。

您可能会考虑更改采用string date的参数的数据类型以采用DateTime对象而不是字符串。 这将更改第二种方法的签名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM