c#,如何简单地改变类成员的顺序

本文关键字:改变 成员 顺序 简单 何简单 | 更新日期: 2023-09-27 18:09:55

嗨,我有一个类派生自另一个类。像这样:

public  class Customer
  {
    public string Date{ get; set; }
    public string InstallationNo{ get; set; }
    public string SerialNo { get; set; }        
  } 
然后我创建了一个名为Customer_U的类,它派生自Customer
 public  class Customer_U:Customer
  {
    public string Bill{ get; set; }            
  }  
我有一个简单的问题。我谷歌了很多次,但没有答案。我有一个列表填充的数据,如:

List<Customer_U> customer= new List<Customer_U>()我用这个列表创建了一个excel。在excel中,列的顺序是这样的:

账单-日期-安装号-序列号

我不想要这个订单。我希望"Bill"成员是最后一列。如何在创建从另一个类派生的类时设置成员顺序

c#,如何简单地改变类成员的顺序

在CLR类中没有定义顺序;这取决于检查类的元数据的实现,以确定如何解释类。

例如,你的Excel库可能使用反射来检查你传递给它的类,反射不能保证处理事物的顺序。

其他实现,如WCF DataContractSerializer或ProtoBuf。. NET通过使用datammember来处理顺序。

也就是说,如果你的库可以处理动态或匿名类型,那么你可以使用其他答案中详细介绍的方法,. net似乎始终按照创建这些类型的顺序来反映它们。

var x = new { Z = "", Y = 1, X = true };
Console.WriteLine(x.GetType().GetProperties().Select(y => y.Name));
但是需要注意的是,这是一个实现细节,不应该被依赖。我想看看你的库是否允许你指定类中的属性和电子表格中的列之间的映射,否则你可能会在将来遇到奇怪的bug !

. net中没有类成员排序。每当有人迭代类中的成员时,他们自己就施加了一些顺序。

默认值似乎是浅优先。因此,在您的示例中,首先枚举所有Customer_U成员,然后是Customer成员。

如果你自己做枚举,没有什么比使用你自己的枚举方法更简单的了:

class A
{
  public string Date { get; set; }
  public string SerialNo { get; set; }
}
class B : A
{
  public string Bill { get; set; }
  public string InstallationNo { get; set; }
}
public static IEnumerable<PropertyInfo> GetProperties(Type type)
{
  if (type.BaseType == typeof(object)) return type.GetProperties().OrderBy(i => i.Name);
  return GetProperties(type.BaseType)
         .Concat
           (
             type
             .GetProperties
               (BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
             .OrderBy(i => i.Name)
           );
}
这个简单的递归方法将输出
Date 
SerialNo 
Bill 
InstallationNo 

Deep-first,字母。如果您不希望按字母顺序排序,您可以省略OrderBy s,但请注意,这样的顺序只是未指定的,而不一定是您在类中使用的顺序。

您可以在构建Excel时使用它,例如-如果有一种在输出数据中施加顺序的方法。如果没有办法在用于输出数据的任何东西中强加您自己的顺序,则可以基于此数据执行到新对象的映射,并希望结果良好—然而,动态执行此操作实际上需要大量工作。

正如其他答案所指出的那样,在。net中没有定义的类属性顺序。

然而,似乎你正在寻找的不是属性本身的排序,但实际上是一种在序列化对象时对属性进行排序的方法,例如到Excel。

使用System.Runtime.Serialization命名空间中的类很容易实现。有各种各样的类可以帮助您控制序列化过程,并允许您按照自己的需要进行具体设置。

最简单的解决方案可能是简单地应用DataMember属性:
[DataContract]
public  class Customer
{
    [DataMember(Order = 1)]
    public string Date{ get; set; }
    [DataMember(Order = 2)]
    public string InstallationNo{ get; set; }
    [DataMember(Order = 3)]
    public string SerialNo { get; set; }        
} 

您可以使用linq:

创建一个新的匿名类
var x = from costumerItem in YourList
        select new { Date = costumerItem.Date, ...and so on };

创建一个类似

的包装器列表
    var reOrderedCustomer = Customer.select(a => new { a.Date, a.InstallationNo ,
 a.SerialNo, a.Bill }).ToList()

或者在填充Customer列表的第一个select方法中这样做(如果您想避免匿名类型)