[英]C# foreach loop thru collection of unknown type
I have a generic method that can be called with 2 different object types, TypeA or TypeB. 我有一个可以用2种不同的对象类型TypeA或TypeB调用的通用方法。 TypeA and TypeB are essentially identical classes except in name only.
TypeA和TypeB本质上是相同的类,只是名称不同。 I am trying to determine how to prevent from having to duplicate the Foreach loop code for each object type.
我试图确定如何避免必须为每种对象类型重复Foreach循环代码。 Is this possible ?
这可能吗 ? thanks.
谢谢。
public class TypeA
{
public string Name { get; set; }
public string Department { get; set; }
public string Total { get; set; }
}
public class TypeB
{
public string Name { get; set; }
public string Department { get; set; }
public string Total { get; set; }
}
private CsvExport GenerateExport<T>(IEnumerable<T> scores)
{
CsvExport export = new CsvExport();
List<TypeA> aList = null;
List<TypeB> bList = null;
Type type = scores.GetType();
if (type.FullName.Contains("TypeA"))
{
aList = scores as List<ObjectaModel>;
}
else if (type.FullName.Contains("TypeB"))
{
bList = scores as List<ObjectbModel>;
}
foreach (var dt in aList)
{
export.AddRow();
export["Name"] = dt.Name;
export["Department"] = dt.Department;
export["Total "] = dt.Total;
};
return export;
}
In this particular case I strongly suggest you delegate the hard work to the CsvHelper library which you can also obtain from Nuget and is used like this... 在这种特殊情况下,我强烈建议您将辛苦的工作委托给CsvHelper库,您也可以从Nuget获取它,并且可以这样使用...
public void ExportToCsv<T>(string filename, ImmutableArray<T> objects)
{
using (var writer = File.CreateText(filename))
{
var csv = new CsvWriter(writer);
csv.WriteRecords(objects);
}
}
The more general answer to your question is that you must either have both classes inherit from a common class or interface or you would have to use reflection to look for an obtain the values of the named properties. 对于您的问题的更一般的答案是,您必须使两个类都从同一个类或接口继承,否则您将不得不使用反射来查找获取命名属性的值。
Using a common interface ... 使用通用界面 ...
public interface IScore
{
int HiScore {get;}
}
public class ScrabbleScore : IScore
{
public int HiScore {get;set;}
}
public class PacManScore : IScore
{
public int HiScore {get;set;}
}
public void Export<T>(IEnumerable<T> scores) where T: IScore
{
foreach(var s in scores)
{
CvsExport["Hi score"]= s.HiScore;
}
}
Using reflection ... 使用反射 ...
var CsvExport = new Dictionary<string,string>();
foreach(var o in scores)
{
//note that checking the type for each object enables you to have heterogenous lists if you want
var objectType= o.GetType();
foreach(var p in objectType.GetProperties())
{
var propertyName = p.Name;
CsvExport[propertyName] = p.GetValue(o).ToString();
}
}
I would treat the reflection solution as the least favoured of the three. 我将反射解决方案视为三者中最不受欢迎的一种。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.