General type parameters using

I am trying to make a universal parser using general type parameters, but I cannot understand the concept of 100%

    private bool TryParse<T>(XElement element, string attributeName, out T value) where T : struct
    {
        if (element.Attribute(attributeName) != null && !string.IsNullOrEmpty(element.Attribute(attributeName).Value))
        {
            string valueString = element.Attribute(attributeName).Value;
            if (typeof(T) == typeof(int))
            {
                int valueInt;
                if (int.TryParse(valueString, out valueInt))
                {
                    value = valueInt;
                    return true;
                }
            }
            else if (typeof(T) == typeof(bool))
            {
                bool valueBool;
                if (bool.TryParse(valueString, out valueBool))
                {
                    value = valueBool;
                    return true;
                }
            }
            else
            {
                value = valueString;
                return true;
            }
        }

        return false;
    }

As you might have guessed, the code does not compile, since I cannot convert int | bool | string in T (e.g. value = valueInt). I am grateful for the feedback, it may not even be possible how I do it. Using .NET 3.5

+5
source share
8 answers

Seeing that you are only writing a large if / then combination, I think it will be easier for you just with a bunch of overloads:

public static class Parser
{
    private static string TryParseCommon(XElement element, string attributeName)
    {
        if (element.Attribute(attributeName) != null && !string.IsNullOrEmpty(element.Attribute(attributeName).Value))
        {
            return element.Attribute(attributeName).Value;
        }

        return null;
    }

    public static bool TryParse(XElement element, string attributeName, out string value)
    {
        value = TryParseCommon(element, attributeName);
        return true;
    }

    public static bool TryParse(XElement element, string attributeName, out int value)
    {
        return int.TryParse(TryParseCommon(element, attributeName), out value);
    }

    public static bool TryParse(XElement element, string attributeName, out bool value)
    {
        return bool.TryParse(TryParseCommon(element, attributeName), out value);
    }
}
+2
source

XElement XAttribute (casts) .NET.

, :

XElement elem = // ...

string value1 = (string)elem.Attribute("myString");
int    value2 = (int)elem.Attribute("myInt");
int?   value3 = (int?)elem.Attribute("myOptionalInt");
bool   value4 = (bool)elem.Attribute("myBool");
+4

, T - , , , T, . , /unboxing, .

+2

Parse TypeConverter.

TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
try
{
    return (T)converter.ConvertFrom(value);
}
+1

.

private bool TryParse<T>(XElement element, string attributeName,out T value)
{
    if (element.Attribute(attributeName) != null && !string.IsNullOrEmpty(element.Attribute(attributeName).Value))
    {
        string valueString = element.Attribute(attributeName).Value;
        TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
        try
        {
            value = (T)converter.ConvertFrom(valueString);
            return true;
        }
        catch
        {
            value = default(T);
            return false;
        }
    }
    value = default(T);
    return false;
}
+1

, ( ) .

+1

, - , . , , .

? , TryParse:

public delegate bool TryParser<T>(string text, out T value);

, :

// uglified code to fit within horizontal scroll area
public bool TryParse<T>
(XElement element, string attributeName, TryParser<T> tryParser, out T value)
{
    value = default(T);

    if (
        element.Attribute(attributeName) != null &&
        !string.IsNullOrEmpty(element.Attribute(attributeName).Value)
    )
    {
        string valueString = element.Attribute(attributeName).Value;
        return tryParser(valueString, out value);
    }

    return false;
}

:

public bool TryParseInt(XElement element, string attributeName, out int value)
{
    return TryParse<int>(element, attributeName, int.TryParse, out value);
}

public bool TryParseBool(XElement element, string attributeName, out bool value)
{
    return TryParse<bool>(element, attributeName, bool.TryParse, out value);
}

.

, , where T : struct .NET. XML- TryParse .

+1
source

This method that I used in the past may also help some

public static T ChangeTypeTo<T>(this object value)
{
    if (value == null)
        return null;

    Type underlyingType = typeof (T);
    if (underlyingType == null)
        throw new ArgumentNullException("value");

    if (underlyingType.IsGenericType && underlyingType.GetGenericTypeDefinition()
                                            .Equals(typeof (Nullable<>)))
    {
        var converter = new NullableConverter(underlyingType);
        underlyingType = converter.UnderlyingType;
    }

    // Guid convert
    if (underlyingType == typeof (Guid))
    {
        return new Guid(value.ToString());
    }

    // Check for straight conversion or value.ToString conversion
    var objType = value.GetType();

    // If this is false, lets hope value.ToString can convert otherwise exception
    bool objTypeAssignable2typeT = underlyingType.IsAssignableFrom(objType);

    // Do conversion
    return (T) (objTypeAssignable2typeT ? 
              Convert.ChangeType(value, underlyingType)
            : Convert.ChangeType(value.ToString(), underlyingType));
}
+1
source

All Articles