Noyan El
Noyan El

Reputation: 133

C#, How to simply change order of class members

Hi I Have a class derived from another class . Like this :

public  class Customer
  {
    public string Date{ get; set; }
    public string InstallationNo{ get; set; }
    public string SerialNo { get; set; }        
  } 

Then I have created a class named Customer_U which derived from Customer

 public  class Customer_U:Customer
  {
    public string Bill{ get; set; }            
  }  

I have simple question. I have google many time but no answer. I have list filled with data like:

List<Customer_U> customer= new List<Customer_U>() I create a excel using this list. In excel colum order is like this :

Bill --- Date --- InstalltionNo --- SerialNo.

Idont want this order. I want "Bill" member to be last columns . How to set order of member when createin a class derived from another class

Upvotes: 6

Views: 4980

Answers (5)

AviD
AviD

Reputation: 13112

As the other answers have pointed out, there is no such thing as a defined order for class properties in .NET.

However, it seems that what you are looking for is not an ordering of the properties themselves, but in fact a way to sort the properties when serializing the objects, e.g. to Excel.

This IS easily implemented using classes from the System.Runtime.Serialization namespace. There are various classes there that could help you control the serialization process, and allow you to be as specific as you want.

The simplest solution would likely be simply applying the DataMember attribute:

[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; }        
} 

Upvotes: 1

Luaan
Luaan

Reputation: 63732

There is no ordering of class members in .NET. Whenever someone iterates over members in a class, they are imposing some order themselves.

The default seems to be shallow-first. So in your case, first all of Customer_U members are enumerated, and then Customer's.

If you do the enumeration yourself, there's nothing easier than simply using your own enumeration method:

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)
           );
}

This simple recursive method will output

Date 
SerialNo 
Bill 
InstallationNo 

Deep-first, alphabetical. If you don't want the alphabetical sort, you can omit the OrderBys, but note that then the order is simply unspecified, not necessarily the order you used in your class.

You can use this when building your Excel, for example - if there's a way to impose an order in the output data. If there's no way to impose your own order in whatever you're using to output your data, you could do a mapping to a new object based on this data, and hope that it turns out well - however, doing this dynamically is actually quite a bit of work.

Upvotes: 1

Lali
Lali

Reputation: 2866

Create a wrapper list like

    var reOrderedCustomer = Customer.select(a => new { a.Date, a.InstallationNo ,
 a.SerialNo, a.Bill }).ToList()

Or do this in your first select method which fills Customer list (If you want to avoid anonymous type)

Upvotes: 0

Dean Ward
Dean Ward

Reputation: 4783

There is no defined order in a CLR class; it is up to the implementation that is inspecting the metadata of the class to determine how a class is interpreted.

For example, your Excel library is probably using reflection to inspect the class you pass it and reflection makes no guarantees as to the order in which things are processed.

Other implementations such as the WCF DataContractSerializer or ProtoBuf.NET handle order through the use of DataMember.

That said, if your library can handle dynamic or anonymous types then you can use the approach detailed in the other answers. .NET seems to consistently reflect these types in the same order that they were created.

var x = new { Z = "", Y = 1, X = true };
Console.WriteLine(x.GetType().GetProperties().Select(y => y.Name));

However it should be noted that this is an implementation detail and should not be relied upon. I'd see if you library allows you to specify the mapping between properties in your class and columns in your spreadsheet otherwise you might run into weird bugs in the future!

Upvotes: 5

israel altar
israel altar

Reputation: 1794

You can create a new anonymous class using linq:

var x = from costumerItem in YourList
        select new { Date = costumerItem.Date, ...and so on };

Afterwards, move this class to the excel.

Upvotes: 0

Related Questions