【发布时间】:2022-01-08 01:01:25
【问题描述】:
我正在尝试在我的扩展方法中获取调用属性的名称,以便在发生异常时使用它。
我的扩展方法如下:
/// <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;
}
}
我正在这样使用它:
var parsedVal = property.ParseOrDefault<Guid>();
或者像这样:
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
}
}
我已经尝试了以下链接中的一些建议,但它们都只是让我得到调用方法的名称,而不是属性的名称。
How to get current property name via reflection?
我的目标是让我的异常看起来像这样的方法和属性:
if (Nullable.GetUnderlyingType(typeof(T)) == null && value.IsNullOrWhitespace())
throw new ArgumentNullException(value, $"{methodName} : value of {propertyName} is null");
【问题讨论】:
-
没有办法得到你想要的。您不必为属性编写扩展方法,而是为值编写扩展方法,一旦从属性中获取了值,该属性就不再涉及到表达式的其余部分。最多您可以从堆栈跟踪中获得表达式编写的位置,但您无法轻易确定该值是从哪个属性获得的。
-
其实是有办法的。 @richard-deeming 帮助我实现了我想要的。我已经将其标记为答案。不过还是谢谢你帮忙^^