[英]Use dynamic data type for TryParse
我有一個過程,允許用戶在 Excel 文件中上傳數據,並在數據經過一系列驗證后保存到數據庫。 一旦這樣的驗證是數據類型驗證,例如,為了防止他們試圖將字符串放入 integer 字段。 這是代碼的摘錄。 調用者(ValidateContentDataType)調用 ValidateDataType() 並將字符串中的屬性信息和數據傳遞給被調用者以執行 TryParse。
public void ValidateContentDataType()
{
//Do stuff
ValidateDataType(typeof(T).GetProperty("nameOfProperty"), data);
//Do stuff
}
private bool ValidateDataType(PropertyInfo propInfo, string dataElement)
{
if (propInfo is null) return true;
if (propInfo.PropertyType == typeof(decimal) || propInfo.PropertyType == typeof(decimal?))
{
return decimal.TryParse(dataElement, out decimal temp);
}
//Other ifs TryParse for different data type....
return true;
}
雖然這有效,但我不喜歡 ValidateDataType() 中的一系列 ifs。 而不是針對不同數據類型的一系列 ifs,如下所示:
if (propInfo.PropertyType == typeof(decimal) || propInfo.PropertyType == typeof(decimal?))
{
return decimal.TryParse(dataElement, out decimal temp);
}
是否有可能有這樣的東西:
return *propertyType*.TryParse(dataElement, out *propertyType *temp);
在風格上,我可能會把它寫成一個switch
語句:
switch (propInfo.PropertyType)
{
case typeof(decimal):
case typeof(decimal?):
return decimal.TryParse(dataElement, out decimal temp);
case typeof(int):
case typeof(int?):
return ...
}
我認為這看起來比多個if
語句要好得多。 但我坦率地承認這是一個主觀意見。
可能有一個解決方案涉及創建一個泛型方法,該方法需要一個實現IParseable接口的類型。 就像是:
private bool ValidateDataType<T>(...) where T:IParseable
但是我還沒有完全弄清楚。 可能是您必須通過反射調用該方法。
好的。 IParsable 給了我我需要的東西。 使用實現 IParsable 的類型參數 T 創建幾個擴展。 然后調用擴展,以便我可以使用來自反射的屬性類型。 為了一些看似瑣碎的事情,似乎要下很多功夫。 無論如何,這是我想出的:
internal class Program
{
static void Main(string[] args)
{
Type myClassType = typeof(MyClass);
PropertyInfo propInfo = myClassType.GetProperty("ForecastYear");
ValidateDataType(propInfo.PropertyType, "2023");
}
static void ValidateDataType(Type propertyType, string input)
{
MethodInfo method = typeof(TryParseExtensions).GetMethod(nameof(TryParseExtensions.TryParse));
MethodInfo generic = method.MakeGenericMethod(propertyType);
object[] args = { input, null };
var parseSuccessful = (bool)generic.Invoke(null, args);
var parsedValue = args[1];
}
}
static class TryParseExtensions
{
public static T Parse<T>(this string s) where T : IParsable<T>
{
return T.Parse(s, null);
}
public static bool TryParse<T>(this string? s, [MaybeNullWhen(false)] out T result) where T : IParsable<T>
{
result = default(T);
if (s == null) { return false; }
try
{
result = s.Parse<T>();
return true;
}
catch { return false; }
}
}
public class MyClass{
public int ForecastYear { get; set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.