我有一个类的公共属性,我的输出细节行是这样编写的:
public static long OutputListToFile(StreamWriter writer, List<DocMetaData> listData)
{
StringBuilder md = new StringBuilder();
int rowcount = 0;
foreach (var c in listData)
{
md.Append(c.Section); md.Append(DocMetaData.SEPARATOR);
md.Append(c.DocClass); md.Append(DocMetaData.SEPARATOR);
md.Append(c.Meeting); md.Append(DocMetaData.SEPARATOR);
md.Append(c.Agency); md.Append(DocMetaData.SEPARATOR);
md.Append(c.Country); md.Append(DocMetaData.SEPARATOR);
md.Append(c.Comment); md.Append(DocMetaData.SEPARATOR);
md.Append(c.Title); md.Append(DocMetaData.SEPARATOR);
md.Append(c.Folder); md.Append(DocMetaData.SEPARATOR);
md.Append(c.File); md.Append(DocMetaData.CARRIAGE_RETURN);
try
{
writer.WriteLine(md.ToString());
rowcount++;
}
catch (Exception ex)
{
log.Fatal("Error in OutputListToFile:\r\n", ex);
}
}
return rowcount;
}
当前md.Append语句必须按照上面的确切顺序放置,以便与写第一行的例程匹配:
private void OutputColumnNamesAsFirstLine(StreamWriter writer)
{
StringBuilder md = new StringBuilder();
PropertyInfo[] columns;
columns = typeof(DocMetaData).GetProperties(BindingFlags.Public |
BindingFlags.Instance);
int i = 0;
foreach (var columnName in columns)
{
i++;
md.Append(columnName.Name); md.Append(DocMetaData.SEPARATOR);
}
writer.WriteLine(md.ToString());
}
是否有一种方法可以重写OutputListToFile中的foreach循环,这样我就可以消除这种排序依赖性。以下是DocMetaData类的片段:
public class DocMetaData
{
public const string SEPARATOR = "\t"; // horizontal tab is delimiter
public const string CARRIAGE_RETURN = "\r";
public string Section { get; set; }
public string DocClass { get; set; }
public string Meeting { get; set; }
public string Agency { get; set; }
public string Country { get; set; }
public string Comment { get; set; }
public string Title { get; set; }
public string Folder { get; set; }
public string File { get; set; }
答案 0 :(得分:2)
如果您考虑使用属性注释属性,此解决方案将起作用:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class OrdinalPositionAttribute : Attribute
{
public int Position { get; private set; }
public OrdinalPositionAttribute(int position)
{
Position = position;
}
}
public class DocMetaData
{
public const string SEPARATOR = "\t"; // horizontal tab is delimiter
public const string CARRIAGE_RETURN = "\r";
[OrdinalPosition(0)]
public string Section { get; set; }
[OrdinalPosition(1)]
public string DocClass { get; set; }
[OrdinalPosition(2)]
public string Meeting { get; set; }
[OrdinalPosition(3)]
public string Agency { get; set; }
[OrdinalPosition(4)]
public string Country { get; set; }
[OrdinalPosition(5)]
public string Comment { get; set; }
[OrdinalPosition(6)]
public string Title { get; set; }
[OrdinalPosition(7)]
public string Folder { get; set; }
[OrdinalPosition(8)]
public string File { get; set; }
private void OutputColumnNamesAsFirstLine(StreamWriter writer)
{
StringBuilder md = new StringBuilder();
var columns = Utility.GetOrderedMembers(typeof(DocMetaData));
int i = 0;
foreach (var columnName in columns)
{
i++;
md.Append(columnName.Name); md.Append(DocMetaData.SEPARATOR);
}
writer.WriteLine(md.ToString());
}
}
public static class Utility
{
public static IEnumerable<MemberInfo> GetOrderedMembers(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
return CreateGetOrderedMembersEnumerable(type);
}
private static IEnumerable<MemberInfo> CreateGetOrderedMembersEnumerable(Type type)
{
return from member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)
let ordinal = member.GetCustomAttributes(typeof(OrdinalPositionAttribute), true)
.OfType<OrdinalPositionAttribute>().FirstOrDefault()
where ordinal != null
orderby ordinal.Position ascending
select member;
}
}
如果您想获取属性的值,则需要在.Cast<PropertyInfo>()
返回的IEnumerable<MemberInfo>
上致电GetOrderedMembers()
。
答案 1 :(得分:1)
考虑为您的DocMetaData(而不是类)使用Dictionary<string, string>
,其中第一个是字段名称,第二个是值。然后,您可以使用columns数组检索值。
答案 2 :(得分:1)
我不确定这是你想要的,但是如果你想按照它们在column
中的顺序编写所有属性的内容,你可以使用它:
foreach (var c in listData)
{
foreach (var column in columns)
{
md.Append(column.GetValue(c, null));
}
}
此代码不使用分隔符和终结符作为原始代码,但我确信您可以轻松解决此问题。