Syz
Syz

Reputation: 45

C# class error CS1061 CS1056

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

Answers (3)

InBetween
InBetween

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.

  1. Why use a string to specify the way you want things ordered? If someone passes in a string 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.

  1. The same issue is happening with your 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

jdweng
jdweng

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

David
David

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 objects 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

Related Questions