Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.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#_.net_Class_File Io_Constructor - Fatal编程技术网

C# 将文件读取到自定义类构造函数

C# 将文件读取到自定义类构造函数,c#,.net,class,file-io,constructor,C#,.net,Class,File Io,Constructor,我有一个如下所示的文本文件: Name One, 123, 13.88, 12.25 Name Two, 321, 12.56, 10.75 foreach(var stuff in Extract<Struff>(@"C:\blah.txt")) { // Do something with stuff } 我需要将其读入一个数组(不能是数组列表),其中包含我创建的自定义类,该类如下所示: class Stuff { //Stuffconstructor (w/ a

我有一个如下所示的文本文件:

Name One, 123, 13.88, 12.25
Name Two, 321, 12.56, 10.75
foreach(var stuff in Extract<Struff>(@"C:\blah.txt"))
{
  // Do something with stuff
}
我需要将其读入一个数组(不能是数组列表),其中包含我创建的自定义类,该类如下所示:

class Stuff
{
    //Stuffconstructor (w/ args)
    public Stuff(string name, int number, decimal rate, double hours)
    {
        System.Console.WriteLine("this constructor has been called");
    }
}
我不太清楚如何在c#中实现这一点。

var parsedList=new List();
string[]lines=System.IO.File.ReadAllLines(@“C:\input.txt”);
foreach(行中的var行)
{
var lineSplit=line.Split(新[]{',},StringSplitOptions.RemoveEmptyEntries);
var stuff=newstuff(lineSplit[0]、Int32.Parse(lineSplit[1])、decimal.Parse(lineSplit[2])、double.Parse([3]);
添加(东西);
}
Stuff[]arrayOfStuff=parsedList.ToArray();

您所拥有的可能是一个非常通用的示例。。。你可能想要一些更健壮和可扩展的东西。因此,让我向您介绍反思

注意

此解决方案使用反射。。。这意味着几件事:

  • 这不是为胆小的人准备的。。。对于一个新的程序员来说,这可能看起来很奇怪
  • 这不是对性能的理解。反射可能比正常代码慢一点
  • 为简单起见,我们假设您有一个公共构造函数
  • 此外,为了简单起见,我们假设构造函数只有具有方法
    Parse()
    或类型
    String
    的参数
解决方案

public static IEnumerable<T> Extract<T>(String path)
{
  var parseList = buildParser(typeof(T));

  foreach (string line in File.ReadLines(path))
  {
    var tokens = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    var args = parseList.Zip(tokens, (parser, value) => parser(value));

    yield return (T)Activator.CreateInstance(typeof(T), args.ToArray());
  }
}

private static IEnumerable<Func<String, Object>> buildParser(Type t)
{
  // For now, we're going to assume you only have one public constructor.
  var ci = t.GetConstructors().First();

  foreach (var pi in ci.GetParameters())
  {
    var parser = fetchParseMethod(pi.ParameterType);
    Func<String, Object> boxingParser;

    if (parser != null)
      boxingParser = value => parser.Invoke(null, new Object[] { value });
    else
      boxingParser = value => value;

    yield return boxingParser;
  }
}

private static System.Reflection.MethodInfo fetchParseMethod(Type t)
{
  return (from mi in t.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
          let parms = mi.GetParameters()
          where mi.Name == "Parse" && parms.Length == 1 && parms.First().ParameterType == typeof(String)
          select mi).FirstOrDefault();
}
公共静态IEnumerable提取(字符串路径)
{
var parseList=buildParser(typeof(T));
foreach(File.ReadLines(路径)中的字符串行)
{
var tokens=line.Split(新[]{',},StringSplitOptions.RemoveEmptyEntries);
var args=parseList.Zip(令牌,(解析器,值)=>parser(值));
yield return(T)Activator.CreateInstance(typeof(T),args.ToArray());
}
}
私有静态IEnumerable构建解析器(类型t)
{
//现在,我们假设您只有一个公共构造函数。
var ci=t.GetConstructors().First();
foreach(ci.GetParameters()中的var pi)
{
var parser=fetchParseMethod(pi.ParameterType);
Func-boxingParser;
if(解析器!=null)
boxingParser=value=>parser.Invoke(null,新对象[]{value});
其他的
boxingParser=value=>value;
收益率-返回boxingParser;
}
}
私有静态System.Reflection.MethodInfo fetchParseMethod(类型t)
{
返回(来自t.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)中的mi)
设parms=mi.GetParameters()
其中mi.Name==“Parse”&&parms.Length==1&&parms.First()。ParameterType==typeof(String)
选择mi.FirstOrDefault();
}
然后使用如下代码:

Name One, 123, 13.88, 12.25
Name Two, 321, 12.56, 10.75
foreach(var stuff in Extract<Struff>(@"C:\blah.txt"))
{
  // Do something with stuff
}
foreach(摘录中的var内容(@“C:\blah.txt”))
{
//用东西做点什么
}
简要概述

这看起来可能有点难以接受。。。但其实很简单:

  • 我们首先看一下所需类型的构造函数(
    Stuff
  • 然后我们检查构造函数的每个
    ParameterType
    ,并获取它的
    Parse()
    方法
  • 然后对文本行的每个元素使用
    Parse()
    方法将其转换为
    对象
  • 有了它,我们可以动态地创建一个对象(
    Stuff

  • 虽然这对你来说可能太过分了。。。我在创作它的时候玩得很开心,希望我们都能从中学习到一些东西。此外,此解决方案非常灵活。如果您稍后向构造函数添加参数,这将自动拾取它。

    您尝试了什么?你到底被困在哪里?你知道如何打开/读取文件吗?需要帮助分析字符串吗?请具体说明。在C#中可以找到数百个读取/解析文本文件的示例。你试过什么吗?我不知道该怎么做。我希望能够逐行读取文件,并将其放入自定义类的on对象中,以便将文件中的测试按以下顺序放入数组:string、int、decimal、double。我是一个初学者,不知道该怎么做。我找到了一些例子,但它们似乎总是针对同一类型。如果我把它放进一个字符串数组,我没有问题,但是我需要数组接受不同的类型谢谢你的帮助(填鸭式回答“给我代码”的问题让我觉得这个解决方案的一个问题是
    ReadAllLines()
    。如果文本文件太大怎么办?没有理由不使用
    ReadLines()
    …您已经在使用
    foreach()
    。在这种情况下,我不能使用列表。您有其他选择吗?使用纯数组,用
    行实例化它。长度
    ,然后将
    foreach
    替换为
    for(int I=0;
    。。。