Sorting happens using a delegate/class that can compare two persons - there is no mandate that you need to compare them using single attribute. For example
People.Sort((p1,p2)=>scoreFunc(p1)-scoreFunc(p2));
EDIT:
If you wish to sort the whole list by a score then this will be the only way (you may change the sorting algorithm but comparison would not change because score is the sorting key). Now above would probably compute the score for some persons multiple time - so one of the optimization could be to cache the person score. For example, scoreFunc can check in the cache (dictionary) to see if score has been already computed or not.
Further optimizations can happen based on your actual requirements and scoring function implementation. For example, assume that you have 10000 persons and you are probably interested in top 20. Assume that person's age and educational qualifications contributes bulk of the score while there are 20 other attributes that do minor contribution. So you can do multi-pass sorting - the first pass may use a score based on only two factors to determine say top 500 persons and then you apply detailed scoring to do get actual top 20.