Skip to main content
added 61 characters in body
Source Link
Matthias Burger
  • 682
  • 2
  • 10
  • 18
  • Code-Style?
  • Performance?
  • Bad Practice?
  • Someone said, this is a misuse of generics. Is it really?
  • Code-Style?
  • Performance?
  • Bad Practice?
  • Code-Style?
  • Performance?
  • Bad Practice?
  • Someone said, this is a misuse of generics. Is it really?
Source Link
Matthias Burger
  • 682
  • 2
  • 10
  • 18

Writing a generic casting extension-method

I'm writing a C# extension-method that converts any object to a type. E.g. the method shall convert a string with value "y" to a true-boolean - so there will be some specific castings like bools, chars, DateTimes,...

Here are some examples of my target:

int number = 3;
string stringNumber = number.To<string>();

stringNumber now should be a string with value equals to "3". (Yeah, there's already the ToString(), it's just an example) another one:

string myDateString = "Mon, 27 Jun 2007 12:34:56 CET";
DateTime myDate = myDateString.To<DateTime>();

myDate now should be a DateTime-object with value equals to a Date on 27th June of 2007 on time 12:34:56.

So, what I did is, I wrote following method:

public static T To<T>(this object @this)
{
    CastTo castedValue = null;

    if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
    {
        DateTime? result = null;

        if (@this is string actualStringValue)
            result = _tryCastStringToDateTime(actualStringValue);

        if (result != null)
            castedValue = new CastTo<DateTime> {Value = result.Value};
    }

    else if (typeof(T) == typeof(bool) || typeof(T) == typeof(bool?))
    {
        bool? result = null;

        if (@this is string actualStringValue)
            result = _tryCastStringToBoolean(actualStringValue);

        else if (@this is int actualIntegerValue)
            result = _tryCastIntegerToBoolean(actualIntegerValue);

        if (result != null)
            castedValue = new CastTo<bool> {Value = result.Value};
    }

    if (castedValue == null || castedValue.IsInitial)
        return (T) Convert.ChangeType(@this, typeof(T));

    return ((CastTo<T>) castedValue).Value;
}

those _tryCast....-methods simply cast an object to the specific type.

Here are my classes CastTo and CastTo<T>.

internal abstract class CastTo
{
    public abstract bool IsInitial { get; }
   
    public object Value { get; set; }
}

internal class CastTo<T> : CastTo
{
    private T _value;

    public override bool IsInitial => EqualityComparer<T>.Default.Equals(Value, default(T));

    public new T Value
    {
        get => _value;
        set
        {
            if (!EqualityComparer<T>.Default.Equals(value, default(T)))
                _value = value;
        }
    }
}

Are there any issues you'd suggest me to change?

  • Code-Style?
  • Performance?
  • Bad Practice?