Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在泛型方法中分配通过反射获得的实例变量_C#_Generics_Reflection_Instance Variables - Fatal编程技术网

C# 在泛型方法中分配通过反射获得的实例变量

C# 在泛型方法中分配通过反射获得的实例变量,c#,generics,reflection,instance-variables,C#,Generics,Reflection,Instance Variables,我想读取并(最终)存储在数据库表中的tab分隔值(TSV)文本文件中的数据。对于TSV文件,每行包含一条记录,但在一个文件中记录可以有2个字段,在另一个文件中可以有4个字段,等等。我编写了处理2个字段记录的工作代码,但我认为这可能是一个通用方法(或两个)的好例子,而不是为每种记录编写新方法。但是,由于两个问题,我无法编写此代码:我无法创建用于保存记录数据的新对象,并且我不知道如何使用反射来一般地填充对象的实例变量 我看了其他几个类似的帖子,包括 下面是可以工作的代码(如果需要的话,可以在Wind

我想读取并(最终)存储在数据库表中的tab分隔值(TSV)文本文件中的数据。对于TSV文件,每行包含一条记录,但在一个文件中记录可以有2个字段,在另一个文件中可以有4个字段,等等。我编写了处理2个字段记录的工作代码,但我认为这可能是一个通用方法(或两个)的好例子,而不是为每种记录编写新方法。但是,由于两个问题,我无法编写此代码:我无法创建用于保存记录数据的新对象,并且我不知道如何使用反射来一般地填充对象的实例变量

我看了其他几个类似的帖子,包括

下面是可以工作的代码(如果需要的话,可以在Windows中使用),也可以是不工作的代码

public class TSVFile
{
    public class TSVRec
    {
        public string item1;
        public string item2;
    }

    private string fileName = "";

    public TSVFile(string _fileName)
    {
        fileName = _fileName;
    }

    public TSVRec GetTSVRec(string Line)
    {
        TSVRec rec = new TSVRec();

        try
        {
            string[] fields = Line.Split(new char[1] { '\t' });

            rec.item1 = fields[0];
            rec.item2 = fields[1];
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show("Bad import data on line: " + 
                Line + "\n" + ex.Message, "Error",
                System.Windows.Forms.MessageBoxButtons.OK,
                System.Windows.Forms.MessageBoxIcon.Error);
        }

        return rec;
    }

    public List<TSVRec> ImportTSVRec()
    {
        List<TSVRec> loadedData = new List<TSVRec>();
        using (StreamReader sr = File.OpenText(fileName))
        {
            string Line = null;
            while ((Line = sr.ReadLine()) != null)
            {
                loadedData.Add(GetTSVRec(Line));
            }
        }

        return loadedData;
    }

    // *** Attempted generic methods ***
    public T GetRec<T>(string Line)
    {
        T rec = new T();  // compile error!
        Type t = typeof(T);

        FieldInfo[] instanceVars = t.GetFields();

        string[] fields = Line.Split(new char[1] { '\t' });

        for (int i = 0; i < instanceVars.Length - 1; i++)
        {
            rec. ??? = fields[i];   // how do I finish this line???
        }

        return rec;
    }

    public List<T> Import<T>(Type t)
    {
        List<T> loadedData = new List<T>();
        using (StreamReader sr = File.OpenText(fileName))
        {
            string Line = null;
            while ((Line = sr.ReadLine()) != null)
            {
                loadedData.Add(GetRec<T>(Line));
            }
        }

        return loadedData;
    }
}
公共类TSVFile
{
公共级TSVRec
{
公共字符串项1;
公共字符串项2;
}
私有字符串fileName=“”;
公共TSVFile(字符串_文件名)
{
文件名=_文件名;
}
公共TSVRec GETSVREC(字符串行)
{
TSVRec rec=新的TSVRec();
尝试
{
string[]fields=Line.Split(新字符[1]{'\t'});
rec.item1=字段[0];
rec.item2=字段[1];
}
捕获(例外情况除外)
{
System.Windows.Forms.MessageBox.Show(“第行导入数据错误:”+
行+“\n”+例如消息“错误”,
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
返回记录;
}
公共列表ImportTSVRec()
{
List loadedData=新列表();
使用(StreamReader sr=File.OpenText(文件名))
{
字符串行=null;
而((Line=sr.ReadLine())!=null)
{
Add(GetTSVRec(Line));
}
}
返回加载的数据;
}
//***尝试了通用方法***
公共T GetRec(字符串行)
{
T rec=new T();//编译错误!
类型t=类型(t);
FieldInfo[]instanceVars=t.GetFields();
string[]fields=Line.Split(新字符[1]{'\t'});
对于(int i=0;i
我看到了那条线 T rec=新的T(); 在上面提到的帖子中,但它对我不起作用


如果可能的话,我将非常感谢您对如何完成这项工作的任何建议。我想了解更多关于将反射与泛型结合使用的知识,因此我不仅想了解如何使用反射,还想了解为什么使用反射。

我希望@EdPlunkett将他的建议作为答案而不是评论发布,这样我就可以将其标记为答案了

总而言之:为了完成我想做的事情,不需要“在泛型方法中分配通过反射获得的实例变量”。事实上,我可以在不使用通用方法的情况下获得通用解决方案:

public class GenRec
{
    public List<string> items = new List<string>();
}

public GenRec GetRec(string Line)
{
    GenRec rec = new GenRec();

    try
    {
        string[] fields = Line.Split(new char[1] { '\t' });

        for (int i = 0; i < fields.Length; i++)
            rec.items.Add(fields[i]);
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show("Bad import data on line: " + Line + "\n" + ex.Message, "Error",
            System.Windows.Forms.MessageBoxButtons.OK,
            System.Windows.Forms.MessageBoxIcon.Error);
    }

    return rec;
}

public List<GenRec> Import()
{
    List<GenRec> loadedData = new List<GenRec>();
    using (StreamReader sr = File.OpenText(fileName))
    {
        string Line = null;

        while ((Line = sr.ReadLine()) != null)
            loadedData.Add(GetRec(Line));
    }

    return loadedData;
}
公共类GenRec
{
公共列表项=新列表();
}
public GenRec GetRec(字符串行)
{
GenRec rec=新的GenRec();
尝试
{
string[]fields=Line.Split(新字符[1]{'\t'});
for(int i=0;i
我刚测试过这个,效果很好


当然,这并不能帮助我学习如何编写泛型方法或使用反射,但我认为…

编译错误是什么?我猜它说您需要通过添加
where T:class
来约束
T
。因为T可能是不稳定的,所以会出现编译错误。“但我认为这可能是一个通用方法(或两个)的好例子,而不是为每种记录编写新方法。”泛型当然会假设一些常见的特性/行为,它由一个通用约束定义,例如类似于
的东西,其中T:MyBaseClass
。在我看来,不同类型上的不同成员与这个wll不匹配。我同意,作为TSV,使用带有字符串值数组的泛型类,或者如果您有具体类型,并且您确实希望以泛型方式实例化它们(而不是使用工厂模式),这更有意义,您只需给他们一个
params string[]
构造函数,然后使用activator createinstance.TSVRec就应该有一个
列表
作为值。添加方法以将它们转换为不同的类型。从本质上讲,如果您正在编写,请找出您需要什么,然后只使用DataRow和DataTable。这里没有问题,泛型非常适合解决,除了可能对编译时已知的某个字段或记录类型的集合使用
List
。当您的泛型类或方法变成一堆反射时,它不是真正的泛型。泛型非常有用,但它们不是大多数问题的正确解决方案。您明白了。Th