0

I have a script called globals.cs where I store global variables that are accessed from other scripts. I have the following class defined there:

public static class business {
    static List<businessVal> _list;
    static business() {_list = new List<businessVal>();}
    public static void Add (businessVal value) {_list.Add(value);}

    public static IEnumerable<businessVal> Get () {return _list;}
    public static businessVal GetItem (string name) {return _list.SingleOrDefault(li => li.name.Equals(name));}
}

public class businessVal {
    public string name {get; set;}
    public int income {get; set;}
}

I'm able to add items to the list and return the full list from other scripts. What I'd like to do is to be able to sort the list either by name or income before looping through the list elements.

I tried adding a sort function to the class as shown below, but I get an error message when using IComparable saying I cannot implement an interface on a static class. What's the beat way of doing this?

public static class business: IComparable {
    // ...
    public int CompareTo(businessVal tag) {
        return businessVal.income.CompareTo(tag.income);
    }
}
Christos
  • 53,228
  • 8
  • 76
  • 108
charles hendry
  • 1,710
  • 4
  • 13
  • 18
  • 4
    Aside from anything else, I would *strongly* advise you to start following .NET naming conventions. I'd also try to move away from static variables as far as possible. – Jon Skeet Jul 18 '16 at 05:40
  • You cannot compare instances of two static classes precisely because you cannot create instances of a static class. You cannot even add instances of this class into a list, precisely because you cannot create instances of it. How does the static class play into the list and the sorting? Can you elaborate? – Lasse V. Karlsen Jul 18 '16 at 05:49

2 Answers2

3

using Linq you can order before looping:

foreach(var b in business.Get().OrderBy(x=> x.name))
{


}

Or add a method:

public static IEnumerable<businessVal> GetOrderedByName() 
{
   return _list.OrderBy(x=> x.name); 
}

Same way works for sorting by income.

Generic Property Selector as you requested in your comments:

public static IEnumerable<businessVal> GetOrderedBy<T>(Func<businessVal, T> selector)
{
    return _list.OrderBy(selector);
}

Side Notes:

You may want to rethink what you are doing here. Storing your lists of data in static fields of a static class is very, very bad idea. Especially if you have a lot of these and your data may become huge.

Also, you may need to read about naming conversions in .NET. You must rename your class to Business.

You may also try to replace the one-line functions with this shorthand (C# 6 feature):

public static IEnumerable<businessVal> Get () => _list;
Zein Makki
  • 29,485
  • 6
  • 52
  • 63
  • As an aside, you should think about what sort of system architecture you have before electing to use Linq. Linq is amazing, don't get me wrong, but it isn't always the most effective solution computationally. I have found that in certain game development scenarios, for example, particular hardware setups made Linq less effective than other solutions. I think 99% of the time, however, it is likely the most convenient, well-documented, and easiest-to-implement way to go :) – Max von Hippel Jul 18 '16 at 06:16
  • [Here](http://stackoverflow.com/questions/1576679/reason-not-to-use-linq) is a discussion of the topic from people significantly more knowledgeable about it than myself. – Max von Hippel Jul 18 '16 at 06:18
  • Thanks for the answer and the tips. Is it also possible to define a generic sort function and pass the property name to it, which it should then sort by? – charles hendry Jul 19 '16 at 14:17
  • 1
    @charleshendry mmm.. `.OrderBy` is already a generic sort method (First method in my answer), you can select the name of the property you want. You can do a method your own, but you would be reinventing the wheel. However if you mean the property selector to be generic, then this is possible, check the edited answer. – Zein Makki Jul 19 '16 at 18:40
  • @user3185569 Yes, I meant the property selector to be generic. Thanks! – charles hendry Jul 21 '16 at 00:44
1

You could try to use LINQ for this purpose:

var orderedByName = business.Get().OrderBy(b=>b.name);

or

var orderedByIncome = business.Get().OrderBy(b=>b.income);
Christos
  • 53,228
  • 8
  • 76
  • 108