使用DataView.RowFilter中的运算符过滤自定义的可比类

时间:2014-01-01 01:34:10

标签: c# csv

CSV文件中的一列包含分数。目前,使用实现DataTable的自定义Fraction类和比较运算符将文件读入IComparable。我希望能够使用RowFilter,例如"Fraction > 1/2"。尽管Fraction实现了Cannot perform '>' operation on WindowsFormsApplication1.Fraction and System.Double并定义了IComparable运算符,但尝试此结果会导致>。我该如何解决这个问题,或者有哪些解决方法?

示例CSV文件

1/2
1/3
2
0
1

阅读CSV文件

TextFieldParser parser = new TextFieldParser(Environment.CurrentDirectory + "\\data.csv");
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
DataTable data = new DataTable();

data.Columns.Add("Fraction", typeof(Fraction));

while (!parser.EndOfData)
{
    string[] input = parser.ReadFields();
    object[] output = new object[input.Length];
    output[0] = new Fraction(input[0]);
    data.Rows.Add(output);
}

这是我在阅读CSV文件后想要做的事情。但是,它会产生Cannot perform '>' operation on WindowsFormsApplication1.Fraction and System.Double

DataView matches = new DataView(data);
matches.RowFilter = "Fraction > 1/2";
dataGridView1.DataSource = matches;

Fraction上课

class Fraction : IComparable
    {
        private int n;
        private int d;

        public Fraction(string value)
        {
            try
            {
                n = Convert.ToInt32(value);
                d = 1;
            }
            catch (Exception)
            {
                n = Convert.ToInt32(value.Split('/')[0]);
                d = Convert.ToInt32(value.Split('/')[1]);
            }
            Reduce();
        }

        private void Reduce()
        {
            int gcd = GCD(n, d);
            n = n / gcd;
            d = d / gcd;

            if (d < 0)
            {
                n = -1 * n;
                d = -1 * d;
            }
        }

        private static int GCD(int a, int b)
        {
            return (b == 0) ? a : GCD(b, a % b);
        }

        private double ToDouble()
        {
            return (double)n / d;
        }

        public override string ToString()
        {
            return n + ((d == 1) ? "" : "/" + d);
        }

        public int CompareTo(object obj)
        {
            Fraction f = (Fraction)obj;
            return this < f ? -1 : this > f ? 1 : 0;
        }

        public override bool Equals(object obj)
        {
            if (obj is Fraction)
            {
                Fraction f = (Fraction)obj;
                return n == f.n && d == f.d;
            }
            else if (obj is int)
            {
                int i = (int)obj;
                return n == i && d == 1;
            }
            else if (obj is double)
            {
                double x = ToDouble();
                double y = (double)obj;
                return !(x < y || x > y);
            }
            else
            {
                return false;
            }
        }

        public override int GetHashCode()
        {
            return n.GetHashCode() * 17 + d.GetHashCode();
        }

        public static bool operator ==(Fraction a, Fraction b) { return a.Equals(b); }
        public static bool operator !=(Fraction a, Fraction b) { return !a.Equals(b); }
        public static bool operator <(Fraction a, Fraction b) { return a.n * b.d < b.n * a.d; }
        public static bool operator >(Fraction a, Fraction b) { return a.n * b.d > b.n * a.d; }
        public static bool operator <=(Fraction a, Fraction b) { return a.n * b.d <= b.n * a.d; }
        public static bool operator >=(Fraction a, Fraction b) { return a.n * b.d >= b.n * a.d; }

        public static bool operator ==(Fraction a, int b) { return a.Equals(b); }
        public static bool operator !=(Fraction a, int b) { return !a.Equals(b); }
        public static bool operator <(Fraction a, int b) { return a.n < b * a.d; }
        public static bool operator >(Fraction a, int b) { return a.n > b * a.d; }
        public static bool operator <=(Fraction a, int b) { return a.n <= b * a.d; }
        public static bool operator >=(Fraction a, int b) { return a.n >= b * a.d; }

        public static bool operator ==(Fraction a, double b) { return a.Equals(b); }
        public static bool operator !=(Fraction a, double b) { return !a.Equals(b); }
        public static bool operator <(Fraction a, double b) { return a.n < b * a.d; }
        public static bool operator >(Fraction a, double b) { return a.n > b * a.d; }
        public static bool operator <=(Fraction a, double b) { return a.n <= b * a.d; }
        public static bool operator >=(Fraction a, double b) { return a.n >= b * a.d; }

        public static implicit operator Fraction(string s) { return new Fraction(s); }
        public static implicit operator string(Fraction f) { return f.ToString(); }
        public static implicit operator double(Fraction f) { return f.ToDouble(); }

    }

0 个答案:

没有答案