简体   繁体   English

C#多个类似的过载问题

[英]C# Multiple similar Overload problem

Scenario 情境

I have the following two overloads that I need in order to instantiate two different derived objects from the base class. 为了实例化基类的两个不同的派生对象,我需要以下两个重载。

Issue 问题

The compiler has a problem with this code since the methods are ambiguous - both taking two strings as arguments. 编译器对此代码有问题,因为方法是模棱两可的-都以两个字符串作为参数。

Question

How can I get round this problem so that the following below code compiles? 如何解决此问题,以便以下代码可以编译?

Code

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

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

Change the second to acecpt a date. 更改第二个以保留日期。 Its right, and its right. 它的权利,也是它的权利。

(I'll assume it really does make sense to accept the date as a string, and that "ric" means something in your domain. It's certainly a general enough issue.) (我认为将日期作为字符串接受确实很有意义,并且“ ric”在您的域中表示某些含义。这肯定是一个足够普遍的问题。)

You can't do this as the two constructors have the same signature, but a nice workaround is to use static factory methods: 您不能这样做,因为这两个构造函数具有相同的签名,但是一个不错的解决方法是使用静态工厂方法:

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

Advantages of static construction methods: 静态构造方法的优点:

  • Doesn't always have to return a new instance (it could apply pooling, etc) 并不总是必须返回一个新实例(它可以应用缓冲池等)
  • Could return null if that was really useful 如果确实有用,则可以返回null
  • Can do useful work before and after construction more easily than a constructor can 可以比构造函数更容易地在构造前后进行有用的工作

Disadvantages: 缺点:

  • Looks odd when you're used to calling "new" 当您习惯称呼“新”时看起来很奇怪
  • Inheritance can become trickier (you'd have to at least make the constructor protected, for non-nested derived types) 继承会变得更加棘手(对于非嵌套的派生类型,您至少必须使构造函数受到保护)

(Both of these suffer from lack of injectability, compared with instance methods on an actual factory type, of course.) (当然,与实际工厂类型上的实例方法相比,这两种方法都缺乏可注入性。)

Why not simply use a constructor that takes 3 arguments ? 为什么不简单地使用带有3个参数的构造函数?

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

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

Have two different functions : 具有两个不同的功能:

RateInstrumentFromDate(blah,date) RateInstrumentFromDate(blah,date)

RateInstrumentFromTenor(blah,tenor) RateInstrumentFromTenor(blah,男高音)

The method signature (including constructor) is not affected by the parameter name. 方法签名(包括构造函数)不受参数名称的影响。 You'll have to change one of the constructors, maybe: 您必须更改其中一个构造函数,也许是:

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

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

You need to give those two constructors different signatures, at the moment they are both 您需要为这两个构造函数提供不同的签名,目前它们都是

foo(string, string);

Otherwise how are you (let alone the compiler) going to know which method you intended to call? 否则,您(更不用说编译器)将如何知道要调用的方法?

You could also place these on different classes, or you could change the type(s) passed into the second constructor, for example the following would both be fine as your second method: 您也可以将它们放置在不同的类上,或者可以更改传递给第二个构造函数的类型,例如,以下两种方法都可以作为第二种方法:

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

If neither of those work in your situation (for example because tenor and date are mututally exclusive) then you should take another look at the design of your class, and whether or not the second case should be handled in a different class. 如果这两种方法都不适合您的情况(例如,由于tenordate互斥,则不行),则应重新考虑类的设计,以及是否应在不同的类中处理第二种情况。

Another alternative that I often use is to delay setting things like the date until after the constructor - again it depends on the design of your class. 我经常使用的另一种选择是将诸如日期之类的设置延迟到构造函数之后-再次取决于类的设计。

Create two static methods, that will create the object for you: 创建两个静态方法,这些方法将为您创建对象:

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

There's a few possible options here. 这里有一些可能的选择。 Without seeing a bit more context, I can't really say which is better, but here are some of them. 没有看到更多背景信息,我无法真正说出哪个更好,但这是其中的一些。

  1. Change the date parameter from a string to a proper Date object to differentiate the two signatures. 将date参数从字符串更改为适当的Date对象,以区分两个签名。

  2. Use the same constructor for both and use something along the lines of DateTime.TryParse to determine if the second argument is a date or tenor. 两者使用相同的构造函数,并沿DateTime.TryParse使用类似的东西来确定第二个参数是日期还是男高音。

  3. Use factory methods instead of a constructor so that they may be named differently. 使用工厂方法而不是构造函数,以便可以使用不同的名称。

Ideas 1 and 3 assume that the calling code knows something about which type of object you are trying to create. 想法1和3假定调用代码了解您要创建的对象类型。 Idea 2 allows the class to remain generic and decide for itself. 想法2允许类保持通用性并自行决定。

Just my 2¢ on the subject. 在这个问题上我只赚2美分。

You can't have two methods that have the same signature . 您不能有两个签名相同的方法。 The signature consists of: 签名包括:

  • The name of the method 方法名称
  • The number of parameters 参数数量
  • The data types and order of the parameters 参数的数据类型和顺序
  • The parameter modifiers 参数修饰符

NOTE: The return type is not part of the signature. 注意:返回类型不是签名的一部分。 Also, it is the types and order of the parameters that are important, not their names. 同样,重要的是参数的类型顺序 ,而不是其名称。

You might consider changing the data type of the parameter that takes string date to take a DateTime object instead of a string. 您可能会考虑更改采用string date的参数的数据类型以采用DateTime对象而不是字符串。 That will change the signature of the second method. 这将更改第二种方法的签名。

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

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