简体   繁体   English

字典的通用/ DRY方式<string, T>

[英]Generic/DRY way to return Dictionary<string, T>

I have a CSV parser that takes the text line-by-line and parses it to values. 我有一个CSV解析器,它逐行接受文本并将其解析为值。 I'm trying to put these values in a Dictionary<string, T> and return it, where T is a descendant of class CharacterStatElement . 我试图将这些值放在Dictionary<string, T>并返回它,其中T是CharacterStatElement类的后代。 I do know what class I want T to be when I parse the CSV, but I don't want to have to rewrite/copypaste the same parser function several times to cover each Type that I want to return from it. 确实知道我在解析CSV时希望T是哪个类,但是我不想多次重写/复制同一解析器函数来覆盖我想从中返回的每个Type。

Should I be writing a Generic Method for the whole thing (and if so, how do I declare that in the Method and return?) or should I be doing some other pattern here? 我应该为整个事情编写一个通用方法(如果是的话,我该如何在方法中声明并返回?),或者我应该在这里做其他方式?

Further info on the CharacterStatElement: Each of the child classes contains several fields that I figure out in the parsing using reflection. 有关CharacterStatElement的更多信息:每个子类都包含几个字段,这些字段是我在使用反射进行解析时得出的。 Each of the child classes has different values, but they ought to all be parsed the same way. 每个子类都有不同的值,但是应该以相同的方式解析所有子类。 Also, this only happens once per button click, not on a loop, so speed isn't an issue. 此外,每次单击仅发生一次,而不是循环执行,因此速度不是问题。 And extracting the meat of the method to wrap it in non-generic methods doesn't do me much good, because most of the parsing method is tied to what the intended Type is by my use of reflection. 提取方法的肉以将其包装在非泛型方法中对我没有多大帮助,因为大多数解析方法都与我使用反射的类型有关。

You can use a generic method. 您可以使用通用方法。 In order to use reflection on the type parameter you can get a Type object using typeof(T) . 为了在类型参数上使用反射,您可以使用typeof(T)获得一个Type对象。 That way you can instantiate that type and set properties dynamically. 这样,您可以实例化该类型并动态设置属性。 This is a rather bad case for generics. 对于泛型而言,这是一个相当糟糕的情况。 If you just used object instead of T everything would pretty much work the same way. 如果您只是使用object而不是T那么几乎所有的工作都将以相同的方式进行。 That's a sign generics are not needed. 这表明不需要泛型。

You also could pass in a "strategy" into the generic function that knows how to convert the raw parsed fields (probably a string[] ) into a T . 您还可以将“策略”传递给通用函数,该通用函数知道如何将原始解析的字段(可能是string[] )转换为T That strategy would be a Func<string[], T> . 该策略将是Func<string[], T> That way there is no reflection at all and this is a clean use case for generics. 这样,根本就没有反射,这是泛型的干净用例。

Or, make the CSV parser return an IEnumerable<string[]> and deal with the conversion to T outside of the CSV parsing method. 或者,使CSV解析器返回IEnumerable<string[]>并在CSV解析方法之外处理到T的转换。

I would suggest that the CharacterStatElement class have a method that knows how to parse the remaining of the input line. 我建议CharacterStatElement类具有一种知道如何解析输入行其余部分的方法。 Each derived class is overridden to perform its specific parsing process. 每个派生类都将被重写以执行其特定的解析过程。 Add any helper methods to the base class so minimize coding needed in the derived classes. 将任何辅助方法添加到基类,以便最小化派生类中所需的编码。

Then you process each line of the CSV file in the following way. 然后,您可以按照以下方式处理CSV文件的每一行。 Parse the start that gives you the information you need to decide on the correct class for parsing the whole line. 解析开始,为您提供确定正确的类以解析整个行所需的信息。 Then create an instance of the correct derived class and pass in the line for processing. 然后创建正确的派生类的实例,并将其传递到行中进行处理。 Then add to your global dictionary the values. 然后将值添加到全局字典中。 Simple. 简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM