Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Sorting a somewhat unknown list of properties

Sorting a somewhat unknown list of properties

Scheduled Pinned Locked Moved C#
databasealgorithmsquestion
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MollyTheCoder
    wrote on last edited by
    #1

    I'm trying to use reflection to generate a report from my classes. The trouble comes with class fields that are lists of other, smaller, classes that will be reported as tables. I can isolate those fields using properties ([ReportAttribute("GenerateTable")])in my class definitions, and get the next layer down with:

    foreach (FieldInfo fi in FieldsThatAreLists)
    {
    IList list = (IList)fi.GetValue(this);

    if (list[0] is MyClass)
    {
    List templist = ((List)list).OrderBy(mc=>mc.Index).ToList();
    list = (IList)newlist;
    }
    else if (repeat for every possible class...)

    ReportGenerate(list);
    }

    Since all of my (smaller) classes have a property called "Index", is it possible to eliminate the maintenance crushing if (list[0] is MyClass)... with something more elegant? And once that's done, the ReportGenerate() method needs to sort the order of things in each class to get the report columns straight. I'm working on doing this with more properties in each class definition, but is there a simpler way?

    I 1 Reply Last reply
    0
    • M MollyTheCoder

      I'm trying to use reflection to generate a report from my classes. The trouble comes with class fields that are lists of other, smaller, classes that will be reported as tables. I can isolate those fields using properties ([ReportAttribute("GenerateTable")])in my class definitions, and get the next layer down with:

      foreach (FieldInfo fi in FieldsThatAreLists)
      {
      IList list = (IList)fi.GetValue(this);

      if (list[0] is MyClass)
      {
      List templist = ((List)list).OrderBy(mc=>mc.Index).ToList();
      list = (IList)newlist;
      }
      else if (repeat for every possible class...)

      ReportGenerate(list);
      }

      Since all of my (smaller) classes have a property called "Index", is it possible to eliminate the maintenance crushing if (list[0] is MyClass)... with something more elegant? And once that's done, the ReportGenerate() method needs to sort the order of things in each class to get the report columns straight. I'm working on doing this with more properties in each class definition, but is there a simpler way?

      I Offline
      I Offline
      Ian Shlasko
      wrote on last edited by
      #2

      Make all of your smaller classes implement a common interface:

      public interface IIndexedList
      {
      int Index { get; }
      }

      That way, you can just test for IIndexedList, and cast to that. As for your next question... You can sort by anything, not just a single property. When you specify mc=>mc.Index, you're defining a function that takes mc as an argument and returns mc.Index. You could return anything you want, as long as OrderBy can sort it... Number, string, date, etc.

      Proud to have finally moved to the A-Ark. Which one are you in?
      Author of the Guardians Saga (Sci-Fi/Fantasy novels)

      M 2 Replies Last reply
      0
      • I Ian Shlasko

        Make all of your smaller classes implement a common interface:

        public interface IIndexedList
        {
        int Index { get; }
        }

        That way, you can just test for IIndexedList, and cast to that. As for your next question... You can sort by anything, not just a single property. When you specify mc=>mc.Index, you're defining a function that takes mc as an argument and returns mc.Index. You could return anything you want, as long as OrderBy can sort it... Number, string, date, etc.

        Proud to have finally moved to the A-Ark. Which one are you in?
        Author of the Guardians Saga (Sci-Fi/Fantasy novels)

        M Offline
        M Offline
        MollyTheCoder
        wrote on last edited by
        #3

        Thanks, Ian. I'll take a look at interfaces. My second question is about controlling the order of class properties returned when reflecting. I need to see the fields themselves to set up columns into which the values will eventually be placed. I can make it work by adding a property declaration for each field, but I was wondering if there's something else available with reflection to control the order in which fields are returned. It seems to depend on inheritance order followed by position within the class declaration, but I can't find it documented so I don't want to depend on it, and in any event, the inheritance ordering messes it up for my case.

        I 1 Reply Last reply
        0
        • M MollyTheCoder

          Thanks, Ian. I'll take a look at interfaces. My second question is about controlling the order of class properties returned when reflecting. I need to see the fields themselves to set up columns into which the values will eventually be placed. I can make it work by adding a property declaration for each field, but I was wondering if there's something else available with reflection to control the order in which fields are returned. It seems to depend on inheritance order followed by position within the class declaration, but I can't find it documented so I don't want to depend on it, and in any event, the inheritance ordering messes it up for my case.

          I Offline
          I Offline
          Ian Shlasko
          wrote on last edited by
          #4

          As far as I know, you can't control what order they come back in, so either you sort it yourself based on name or type, or you tag them with attributes.

          Proud to have finally moved to the A-Ark. Which one are you in?
          Author of the Guardians Saga (Sci-Fi/Fantasy novels)

          1 Reply Last reply
          0
          • I Ian Shlasko

            Make all of your smaller classes implement a common interface:

            public interface IIndexedList
            {
            int Index { get; }
            }

            That way, you can just test for IIndexedList, and cast to that. As for your next question... You can sort by anything, not just a single property. When you specify mc=>mc.Index, you're defining a function that takes mc as an argument and returns mc.Index. You could return anything you want, as long as OrderBy can sort it... Number, string, date, etc.

            Proud to have finally moved to the A-Ark. Which one are you in?
            Author of the Guardians Saga (Sci-Fi/Fantasy novels)

            M Offline
            M Offline
            MollyTheCoder
            wrote on last edited by
            #5

            I think I've got the interface working, and the test works: if(list[0] is IIndexedListItem). I'm getting an InvalidCastException when I try to cast the list: List<IIndexedListItem> newlist = (List<IIndexedListItem>)list; Instead, I tried:

            List<IIndexedListItem> newlist = new List<IIndexedListItem>();
            foreach(IIndexedListItem item in list)
            {
            newlist.Add(item);
            }
            newlist = newlist.OrderBy(p => p.Index).ToList();

            This does what I need, so I'm back to work, I just wonder if I'm missing something easy about casting the lists.

            I A 2 Replies Last reply
            0
            • M MollyTheCoder

              I think I've got the interface working, and the test works: if(list[0] is IIndexedListItem). I'm getting an InvalidCastException when I try to cast the list: List<IIndexedListItem> newlist = (List<IIndexedListItem>)list; Instead, I tried:

              List<IIndexedListItem> newlist = new List<IIndexedListItem>();
              foreach(IIndexedListItem item in list)
              {
              newlist.Add(item);
              }
              newlist = newlist.OrderBy(p => p.Index).ToList();

              This does what I need, so I'm back to work, I just wonder if I'm missing something easy about casting the lists.

              I Offline
              I Offline
              Ian Shlasko
              wrote on last edited by
              #6

              Try list.Cast<IIndexedListItem>()

              Proud to have finally moved to the A-Ark. Which one are you in?
              Author of the Guardians Saga (Sci-Fi/Fantasy novels)

              1 Reply Last reply
              0
              • M MollyTheCoder

                I think I've got the interface working, and the test works: if(list[0] is IIndexedListItem). I'm getting an InvalidCastException when I try to cast the list: List<IIndexedListItem> newlist = (List<IIndexedListItem>)list; Instead, I tried:

                List<IIndexedListItem> newlist = new List<IIndexedListItem>();
                foreach(IIndexedListItem item in list)
                {
                newlist.Add(item);
                }
                newlist = newlist.OrderBy(p => p.Index).ToList();

                This does what I need, so I'm back to work, I just wonder if I'm missing something easy about casting the lists.

                A Offline
                A Offline
                AspDotNetDev
                wrote on last edited by
                #7

                If you don't want to use all that fancy LINQ stuff, you can use List.ConvertAll to convert from a list of one type to a list of another type:

                List<Animal> myAnimals = (new List<Dog> { new Dog() }).ConvertAll<Animal>(delegate(Dog d) { return d; });

                [Forum Guidelines]

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups