Implementing IConvertible like functionality for non modifiable types

5.1k views Asked by At

I have an issue with IConvertible, in short: If DateTimeOffset implemented IConvertible I would not have an issue.

You cannot use extension methods to implement an interface, so that road is closed. The struct DateTimeOffset is not partial so it cannot be extended that way.

When reading up in some MSDN docs I came across the TypeCode enum, which seems to be needed for IConvertible to work properly. And to my disappointment the enum did not contain TimeSpan either, which closes the option of using a Tuple-like structure with DateTime and TimeSpan (ie DateTimeOffset =P)

My question is as follows: How would you implement a DateTimeOffset-equivalent which has rudimentary IConvertible or similar support?

The implementation is concerning a fancy lazy dictionary implementation with [index,TType] where TType : IConvertible (both setters, getters and try-getters) functionality, and it needs to be able to store timezone specific data.

My ideas so far:

  • Create a new ISuperConvertible interface which in reality is just an extension to IConvertible and make DateTimeOffset a special case. This would break our IConvertible support in general, but work for this very specific case. Pros and cons?

  • Use two "slots" for storing DateTimeOffsets, one for the DateTime and one for the int halfhour offset (all timezones are not whole hours =/). Then we lose the cache[ApplicationStrings.LastUpdate, default : DateTimeOffset.Min] functionality.

Those represent my main thoughts, ie break DateTimeOffset and keep IConvertible or break IConvertible and keep DateTimeOffset.

I'm still new to the intrinsic peculiarities of C#, so any insight would be helpful. What are your thoughts?

EDIT: Additions:

  • There is a working solution right now which uses DateTime (fixed timezone), but now timezone is needed as well, optimal scenario would be to just use DateTimeOffset everywhere instead. The question in its essence is not about refactoring, but my specific problem is.
  • It is a quite large application, it uses entity framework and other more obscure frameworks for communicating with different services and storages, therefore keeping it a simple System defined type would not break LINQ-to-X optimizations etc (I have no idea how hard these are to do yourself).
  • I'm against splitting data, since I have no idea when another guy will come along and notice that there is a DateTime used for timestamping, and use it without taking the offset (timezone) into account.
1

There are 1 answers

2
Kirill Bestemyanov On

You can create your own wrapper class on DateTimeOffset that will implement IConvertible. This class will have property of DateTimeOffset, that you will use for your wrapper properties and methods. And you implement methods of IConvertible for it. Example:

public class DTOffset:IConvertible
{
    private DateTimeOffset DateTimeOffset;

    //Implementation of IConvertible
    public long ToInt64(IFormatProvider provider)
    {
        return DateTimeOffset.Ticks;
    }

    public DateTime ToDateTime(IFormatProvider provider)
    {
        DateTimeOffset.DateTime;
    }
    //and so on

    //wrapper properites of DateTimeOffset:
    public int DayOfYear{get{return DateTimeOffset.DayOfYear;}}

    public DateTime Date{get{return DateTimeOffset.Date;}}
    //and so on
}