metode umum untuk memvalidasi int, double. Bagaimana cara menggunakan GetType()?

Saya mencoba menulis metode validasi. Misalnya: untuk double tampilannya seperti ini:

   protected bool ValidateLoopAttributes(string i_value, double i_threshold)
       {
        double result;
        if (!(double.TryParse(i_value, out result) && result >= i_threshold))
        {
            return false;
        }
        return true;
    }

Apakah mungkin untuk menulis ini sebagai:

     protected bool ValidateLoopAttributes<T>(string i_value, T i_threshold)

dan kemudian gunakan sesuatu seperti

             T.GetType().TryParse() // how can i use here the type's methods??

Apakah menggunakan pernyataan switch/if satu-satunya cara untuk melakukan ini? Misalnya:

    If (T.GetType() is int) 
        Int32.TryParse(i_threshold)

Apakah ada cara yang lebih elegan?


person Dan Dinu    schedule 13.04.2012    source sumber
comment
Periksa jawaban Marc Gravell di posting ini: stackoverflow.com/questions/1654871/   -  person Marco    schedule 13.04.2012
comment
GetType() adalah metode instan, jadi T.GetType() bahkan tidak boleh dikompilasi. Anda perlu menggunakan typeof(T).   -  person Cristian Lupascu    schedule 13.04.2012
comment
Mengapa harus bersusah payah melakukan semua ini? Jika Anda hanya khawatir tentang float dan integer, mengapa tidak memiliki dua kelebihan saja, ValidateLoopAttributes(string i_value, double i_threshold) dan ValidateLoopAttributes(string i_value, int i_threshold) (atau long)?   -  person Rawling    schedule 13.04.2012


Jawaban (4)


Coba ini:

static class Ext
{
    public static bool TryParse<T>(string s, out T value)
    {
        TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
        try
        {
            value = (T)converter.ConvertFromString(s);
            return true;
        }
        catch
        {
            value = default(T);
            return false;
        }
    }
    public static bool ValidateLoopAttributes<T>(string i_value, T i_threshold) 
           where T : IComparable
    {
        T outval;
        if (TryParse<T>(i_value, out outval))
            return outval.CompareTo(i_threshold) >= 0;
        else return false;
    }
}

Jawaban saya menggunakan jawaban Marc Gravell yang diambil dari di sini.
Dengan ini Anda dapat melakukannya

bool b1 = Ext.ValidateLoopAttributes<int>("5", 4);
bool b2 = Ext.ValidateLoopAttributes<double>("5.4", 5.5d);

Jika dirasa bermanfaat, Anda juga dapat menggunakan metode ekstensi

public static bool ValidateLoopAttributes<T>(this string i_value, T i_threshold) 
       where T : IComparable { }

yang mengarahkan Anda untuk menggunakannya

bool b1 = "5".ValidateLoopAttributes<int>(4);
bool b2 = "5.4".ValidateLoopAttributes<double>(5.5d);
person Marco    schedule 13.04.2012

Saat ini Anda sedang menggabungkan dua hal dalam metode Anda - parsing dan aturan bisnis. Anggaplah Anda memanggil ValidateLoopAttributes(value, 4) dan mengembalikan false. Kemungkinan alasannya:

  1. String tidak mengandung nilai. Misalnya. kosong, beberapa karakter, dll.
  2. String tidak mengandung nilai integer. Misalnya. itu memiliki nilai ganda.
  3. String berisi nilai integer, tetapi melebihi ambang batas.
  4. Tidak ada konverter yang ditentukan untuk tipe Anda.

Dalam kasus pertama Anda memiliki data yang tidak valid di sumber Anda. Dalam kasus kedua Anda memiliki kode yang tidak valid, yang seharusnya menggunakan double. Dalam kasus ketiga, kodenya oke, tetapi aturan bisnis dilanggar. Dalam kasus terakhir (yang bukan kasus ganda atau bilangan bulat, tetapi jika Anda menulis kode generik tanpa batasan jenis, Anda mengizinkan orang lain memanggilnya dengan jenis apa pun) juga ada masalah dalam kode.

Jadi, pikirkan tentang memisahkan aturan bisnis dan mengurai data.

Foo foo = Parse(xml);
RunBusinessRules(foo); 
person Sergey Berezovskiy    schedule 13.04.2012

public static bool ValidateLoopAttributes<T>(string value, T threshold)
    where T : IComparable
{
    try
    {
        var parseMethod = typeof(T).GetMethod("Parse", new[] {typeof (string)});
        var result = (T) parseMethod.Invoke(null, new object[] {value});
        return result.CompareTo(threshold) < 0;
    }
    catch (Exception)
    {
        return false;
    }
}

Jelas, ini hanya berfungsi untuk tipe dengan metode Parse statis.

person Scroog1    schedule 13.04.2012

Dapat mencoba menggunakan sesuatu seperti ini untuk memeriksa apakah ini bilangan bulat atau bukan:

public static bool IsNumericValue(string val, System.Globalization.NumberStyles NumberStyle)
{
    double result;
    return Double.TryParse(val,NumberStyle,
        System.Globalization.CultureInfo.CurrentCulture,out result);
}

so on

 IsNumericValue("1.2", System.Globalization.NumberStyles.Integer) // FALSE 

dan seterusnya

 IsNumericValue("12", System.Globalization.NumberStyles.Integer)  // TRUE

Perhatikan bahwa dalam contoh ini saya menggunakan CurrectCulture, sesuaikan dengan kebutuhan Anda, jika berbeda.

person Tigran    schedule 13.04.2012