泛化一个方法来处理各种对象

本文关键字:处理 对象 方法 一个 泛化 | 更新日期: 2023-09-27 18:02:17

在我正在编写的程序中,我决定使用我自己的数据类型而不是任何其他数据库(出于教育目的)。

数据保存为csv文件,我有一个方法将。csv转换为简单的字符串[,].

每个类X作为它自己的字符串[,]到列表的转换器。在前3节课之后,我开始玩泛型和反射。我确实成功地将普通列表转换为字符串[,],但做相反的事情开始看起来很困难。

我实现List到string[,]的方式是:

public string[,] ToArray(object[] sender)
    {
        if (sender.Length==0)
        {
            return null;
        }
        string[,] ret; 
        PropertyInfo[] props;
        if (sender.Length > 0)
        {
            props = sender[0].GetType().GetProperties();
            ret = new string[props.Length, sender.Length];
        }
        else
        {
            return null;
        }
        for (int i=0;i<sender.Length;i++)
        {

            for (int p = 0; p < props.Length; p++)
            {
                object value=props[p].GetValue(sender[i], null);
               if (value!=null) ret[p, i] = value.ToString();
            }

        }
        return ret;

    }

和for让我们说类Windows(string Name, double Size, bool Blinds)

i转换数组[,]到Windows(非常普遍),像这样:

public static List<Windows> ToList(string[,] arra)
    {
        List<Windows> ret = new List<Windows>(); // change Windows to anything
        int col = array.GetLength(1);
        int row = array.GetLength(0);
        PropertyInfo[] props=PropArray(new Windows());
        int propslen=props.Length;
        for (int c = 0; c < col; c++)
        {
            Windows entry=new Windows();
            for (int r = 0; r < propslen; r++)
            {
                Type pt = props[r].PropertyType;
                if (pt==typeof(string))
                    props[r].SetValue(entry,array[r,c],null);
                else
                    if (pt==typeof(int))
                    {
                        int i=0;int.TryParse(array[r,c],out i);
                    props[r].SetValue(entry,i,null);
                    }
                else
                    if (pt==typeof(bool))
                    {
                        bool i = false; bool.TryParse(array[r, c], out i);
                    props[r].SetValue(entry,i,null);
                    }
                    else
                        if (pt == typeof(double))
                        {
                            double i = 0; double.TryParse(array[r, c], out i);
                            props[r].SetValue(entry, i, null);
                        }
                    else
                if (pt==typeof(DateTime))
                    {
                        DateTime i = DateTime.MinValue; DateTime.TryParse(array[r, c], out i);
                    props[r].SetValue(entry,i,null);
                    }


            }
            ret.Add(entry);

            }
        return ret;

        }

我所需要做的就是把单词"Windows"替换为任何其他数据类型,它就工作了。

真正的问题是我如何泛化它来接收一个类型并由它自己创建一个实例列表?

这可能吗?

提前感谢,加布里埃尔

泛化一个方法来处理各种对象

这不是万无一失的,但是您可以使用泛型。比如:

public static List<T> ToList<T>(string[,] arra) // T can be anything
    where T : new()                             // as long as it has a default constructor
{
    List<T> ret = new List<T>();
    int col = array.GetLength(1);
    int row = array.GetLength(0);
    PropertyInfo[] props=PropArray(new T());
    int propslen=props.Length;
    for (int c = 0; c < col; c++)
    {
        T entry=new T();
// ...

您所做的实际上是一种序列化格式。如果对象是没有复杂引用的值,则序列化格式相对简单。简单的xml或json是常见的格式。也许你应该考虑使用json?

如果你选择"roll your own",为什么不尝试使用属性名作为键呢?用类名作为键/值列表的前缀,并在反序列化时实例化对象。格式示例

MyApplication.Person, MyAssembly
Name=Steve
Age=30
MyApplication.Person, MyAssembly
Name=Bob
Age=54

要反序列化,读取类名,使用FormatterServices.GetUninitializedObject()进行实例化,以获得类的空实例。然后使用该类的属性信息,设置文件中后面的键/值对中的值。这本质上是一个简化的JSON表示法(不支持列表,映射等)