Reputation: 45
I want to code sorting class 'Person'.
Class 'Person' include "Name", "Age", "Major".
Like this.
class Person
{
public int Age;
public string Name;
public string Major;
public override string ToString()
{
return Name + ": " + Age + " , Major in " + Major;
}
public Person(int Age, string Name, string Major)
{
this.Age = Age;
this.Name = Name;
this.Major = Major;
}
}
I learn by book, and there is only "DescSortByName" code:
static bool DescSortByName(object arg1, object arg2)
{
Person person1 = arg1 as Person;
Person person2 = arg2 as Person;
return person1.Name.CompareTo(person2.Name) < 0;
}
But I wanna code that user can choice what kind of attributes and Descending of Ascending.
So I coded like this:
static bool SortByAll(object arg1, object arg2, string what, string updown)
{
Person person1 = arg1 as Person;
Person person2 = arg2 as Person;
int comp;
what = what.ToLower();
switch (what)
{
case "name":
comp = arg1.Name.CompareTo(arg2.Name); //1.
break;
case "age":
int xa = arg1.Age; int ya = arg2.Age; //2.
if (xa > ya) { comp = 1; }
else { comp = -1; }
break;
case "major":
comp = arg1.Major.CompareTo(arg2.Major); //3.
break;
}
if (updown == "Descending")
{ return comp == -1; } //4.
else { return comp == 1; }
}
The former absolutely works well, but mine(the latter) doesn't and I can't find what is difference between them.
In error list, there are two kinds of errors.
In 1, 2, 3(I commended like //1. in my code), error is CS1061:
'object' does not contain a definition for 'Name' and no extension method 'Name'
accepting a first argument of type 'object' could be found
(are you missing a using directive or an assembly reference?).
and in 4, error is CS1056:
Use of unassigned local variable 'comp'.
...
plz let me know what I did wrong and how can I fix it.
ps. I'm Korean, so I'm not good at English, so these sentences may be awkward. I'm sorry.
pps. I'm very glad to ALL other kind of feedback!
ppps. I didn't expect the type of arg1
and arg2
is not a Person
.
Upvotes: 0
Views: 337
Reputation: 32740
There are quite a few issues with your code.
Regarding the error you are getting, your method is comparing to instances typed object
. object
has no idea about Age
or Name
, your class Person
does, so you should change the method signature to:
static bool SortByAll(Person arg1, Person arg2, string what, string uptown)
That said, lets try to make your method a little less brittle and safer.
descending
instead of Descending
, the method will not work properly, and whats worse, the compiler will not warn the consumer that there is a bug in his code.In your case it would be much simpler to use a bool
likeso:
static bool SortByAll(Person arg1, Person arg2, string what, bool descending)
Now its obvious that there is no margin for mistake. You can either pass true
or false
and both are legal options for your method. If it were the case that you should need 3 or more options, then a good way to go would be to use enumerations.
what
argument. What happens if the consumer misspells the property or simply specifies one that Person
does not implement. Again the compiler will not be able to warn of such an error and your program will crash in runtime which is not good.In this case, you need a type safe way to let the consumer define the property to use when ordering. Welcome to generics, Func<>
and lambdas.
static bool SortByAll<T>(Person arg1, Person arg2, Func<Person, T> what, bool descending)
And you would use it like this:
SortByAll(Person p1, Person p2, p => p.Age, true);
I leave the implementation o said method to you.
Upvotes: 0
Reputation: 34421
throw the book away. Do it the proper way
public class Person
{
public int Age;
public string Name;
public string Major;
public override string ToString()
{
return Name + ": " + Age + " , Major in " + Major;
}
public Person(int Age, string Name, string Major)
{
this.Age = Age;
this.Name = Name;
this.Major = Major;
}
public int CompareTo(Person person, string updown, string what)
{
int comp = 0;
what = what.ToLower();
switch (what)
{
case "name":
comp = this.Name.CompareTo(person.Name); //1.
break;
case "age":
comp = this.Age.CompareTo(person.Age);
break;
case "major":
comp = this.Major.CompareTo(person.Major); //3.
break;
}
if (updown == "Descending")
{
return comp *= -1;
} //4.
else
{
return comp;
}
}
}
Upvotes: 0
Reputation: 218808
You have these variables in your method (as method parameters):
object arg1, object arg2
And you try to use them here:
arg1.Name.CompareTo(arg2.Name)
Just as the error states, object
doesn't have a property called Name
. You could use your Person
objects instead:
person1.Name.CompareTo(person2.Name)
Though you run the risk of a NullReferenceException
if those object
s aren't of type Person
. Since the method assumes that they must be of type Person
, just remove the Person
variables entirely and change the method to expect that type:
static bool SortByAll(Person arg1, Person arg2, string what, string updown)
Here you're using the comp
variable:
if (updown == "Descending")
{ return comp == -1; } //4.
else { return comp == 1; }
But nowhere do you guarantee that the variable will ever have a value. Which is what the compiler is warning you about. Just give it a default value when you declare it:
int comp = 0;
Upvotes: 1