简体   繁体   English

提供基类隐式构造的实现

[英]Provide implementation for implicit construction in base class

Is there a way, in a base class, to provide an implicit conversion that works for all inherited classes? 在基类中,有没有一种方法可以提供适用于所有继承类的隐式转换?

Here's a simplified example of a class I'm using: 这是我正在使用的类的简化示例:

public class Date1 {
   public Date1(DateTime value) {
       Value = value;
   }

   public DateTime Value { get; set; }

   public static implicit operator Date1(string value) {
      DateTime dt;
      DateTime.TryParse(value, out dt);
      return new Date1(dt);
   }

   public void SerializeTo(TextWriter textWriter)
   {
      textWriter.Write("{0:yyMM}", Value);
   }
}

I plan to make Date2 and Date3 classes whose only differences from Date1 are the names and the particular format specifier in SerializeTo . 我计划把Date2Date3类,它们唯一的区别从Date1的名称,并在特定的格式说明SerializeTo It seems like I should be able to put the implicit operator into a base class from which all these classes inherit. 看来我应该能够将隐式运算符放到所有这些类都继承自的基类中。 Is that possible? 那可能吗? The problem is that in the base class, I have to return an instance of the correct subclass, and I don't know if that's even possible, or advisable. 问题在于,在基类中,我必须返回正确子类的实例,而且我不知道这是否可能或明智。

Or is there a better way to construct these classes? 还是有更好的方法来构造这些类?

PS Please see my follow-up question where I request critique on a possible way to accomplish what I'm asking for. 附言:请参阅我的后续问题 ,在这里我要求对完成我所要求的方法的批评。 (I only thought of this some time after asking this question.) (我问这个问题后才想到这一点。)

@DavidArno already mentioned in a comment why it's not possible technically, but let's forget that for the moment and consider an example of what you are trying to achieve. @DavidArno在评论中已经提到了为什么在技术上不可能做到这一点,但让我们暂时忘记这一点,并考虑一个您要实现的目标的示例。

Let's say I have a method with the following signature: ConsumeDate1(Date1 date) . 假设我有一个带有以下签名的方法: ConsumeDate1(Date1 date) If you provide such "magical conversion" as you described, I should be able to pass a string to the method ( ConsumeDate1("1507") ), implicit conversion should take place and the result should be given to the method implementation. 如果您提供了您所描述的“神奇转换”,我应该能够将字符串传递给方法( ConsumeDate1("1507") ),应该进行隐式转换,并将结果提供给方法实现。 The only information the conversion has, is that the input is a string, and that output should be Date1 or a derived class . 转换具有的唯一信息是输入是字符串,并且输出应为Date1 或派生类 How would the conversion ever know which class to choose? 转换如何知道选择哪个班级? The only one it knows about is Date1 . 它唯一知道的是Date1 Even if you were able to redefine the conversion in Date2 and Date3 , the conversion operation couldn't magically decide, which implementation to convert to. 即使您能够在Date2Date3重新定义转换,转换操作也无法神奇地确定要转换为哪个实现。

In cases like this, inheritance unfortunately doesn't help. 在这种情况下,不幸的是继承没有帮助。 You can for example provide static factory methods ( Parse , FromString ...) on each of the derived classes. 例如,您可以在每个派生类上提供静态工厂方法( ParseFromString ...)。

The problem with these obviously is that you have to explicitly choose which type to use - ConsumeDate1(Date3.Parse("1507")) , but we've already established that the conversion cannot figure that out itself and would need help anyway. 这些问题显然是,您必须显式选择要使用的类型ConsumeDate1(Date3.Parse("1507")) ,但是我们已经确定转换无法确定其本身,并且仍然需要帮助。

Another issue is that you cannot enforce those static method on all derived classes by C#'s type system. 另一个问题是,您不能通过C#的类型系统在所有派生类上强制使用这些静态方法。 If you want to make sure they are implemented (at least in the code you own), you can use Convetion Testing and reflectively check that all subclasses of Date1 contain such static method. 如果要确保实现它们(至少在您拥有的代码中),则可以使用对流测试并反思地检查Date1所有子类Date1包含此类静态方法。

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

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