Reputation: 133
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
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
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 OrderBy
s, 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
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
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
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