Home > database >  How can I get/address the name of the calling property in my extension method
How can I get/address the name of the calling property in my extension method

Time:12-02

I'm trying to get the name of a calling property in my extension method to use it in case of an exception.

My extension method looks like this:

/// <summary>
/// Parse string to value of T 
/// Can throw on Default or Exception
/// </summary>
/// <typeparam name="T">Type to Convert to</typeparam>
/// <param name="value">value for conversion</param>
/// <param name="throwOnDefault">set <see langword="true"/>for throw on Exception or Default</param>
/// <returns></returns>
/// <exception cref="NotSupportedException">If string can't be converted</exception>
/// <exception cref="Exception">If converted value is defaut</exception>
public static T ParseOrDefault<T>(this string value, bool throwOnDefault = false, [CallerMemberName]string methodName = "")
{
    if (Nullable.GetUnderlyingType(typeof(T)) == null && value.IsNullOrWhitespace()) 
        throw new ArgumentNullException(value, $"{methodName} : value of string is null");

    System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));

    try
    {
        var converted = (T)converter.ConvertFromString(null, System.Globalization.CultureInfo.InvariantCulture, value);

        var type = converted?.GetType();

        if (type != null && type.IsValueType)
        {
            var defaultValue = Activator.CreateInstance(type);
            return !value.Equals(defaultValue) ? converted : throw new Exception("Converted value is default value");
        }
        else
        {
            return converted;
        }
    }
    catch (Exception)
    {
        if (throwOnDefault)
            throw;
        else
            return default;
    }
}

And I'am using it like this :

var parsedVal = property.ParseOrDefault<Guid>();

or like this :

public void SomeMethod (RequestModel request)
{
    Dto dto = new()
    {
        intProperty = request.IntValue.ParseOrDefault<int>(), // IntValue in the requestObject is a string 
        guidProperty = request.GuidValue.ParseOrDefault<Guid>() // GuidValue in the requestObject is a string
    }
}

I tried already some of the suggestions in the following link but they all just get me the name of the calling method, not the name of the property.

How to get current property name via reflection?

My Goal is to get the method and property to make my exceptions look something like this:

if (Nullable.GetUnderlyingType(typeof(T)) == null && value.IsNullOrWhitespace()) 
        throw new ArgumentNullException(value, $"{methodName} : value of {propertyName} is null");

CodePudding user response:

[CallerMemberName] will give you the name of the method/property which called your extension method. In your example, that would be SomeMethod.

If you can update to C# 10, you can use the [CallerArgumentExpression] attribute instead.

public static T ParseOrDefault<T>(this string value, bool throwOnDefault = false, [CallerArgumentExpression("value")] string memberName = "")

For request.IntValue.ParseOrDefault<int>(), the memberName would be set to request.IntValue.

If you're using .NET Framework, you can still use this approach so long as you're using an up-to-date compiler. You will just need to manually define the attribute class.

  • Related