簡體   English   中英

為 TryParse 使用動態數據類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM