CompareTo method not working, it won't get Alb

2019-07-31 10:57发布

I'm trying to get my CompareTo method to from Artist class to work, however it won't get AlbumName from the Album class. I'm pretty sure it's an issue with IComparable on the Album class. Please help with code specific answers, thankyou.

Error 1 'Assignment.Album' does not implement interface member 'System.IComparable.CompareTo(object)'

Album Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Assignment
{
    class Album : IComparable
    {
        public string albumName;

        public Album(string albumName)//constructors
        {
            this.albumName = albumName;

        }

        public string AlbumName
        {
            get { return albumName; }
            set { albumName = AlbumName; }
        }
    }
}

Artist Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Assignment
{
    public class Artist : IComparable
    {
        private String name;
        int members = 4;//default number of members
        //string albumName;

        LinkedList<Artist> albums = new LinkedList<Artist>();

        public override string ToString()//to make my own toString method
        {
            return ("Name: " + name + "Number of Members: " + members);
        }

        public Artist(string name, int members)//constructors
        {
            this.name = name;
            this.members = members;
        }

        public string Name
        {
            get { return name; }
            set { name = Name; }
        }

        public int Members
        {
            get { return members; }
            set { members = value; }
        }

        public int CompareTo(object obj)
        {
            if (obj is Artist) //compare by name
            {
                Artist other = (Artist)obj;
                return name.CompareTo(other.name);//artist name
            }
            if (obj is string) //compare against list of album titles
            {
                string other = obj.ToString();

                    if (obj.Equals(name.AlbumName))
                        return 0;

                return -1;
            }
            else
                return -999;  //indicates can’t make a comparison    
        }

    }
}

1条回答
看我几分像从前
2楼-- · 2019-07-31 11:29

The error message you post says that there is no Compare(object) method in your Album class. Your code confirms that. So... add one!

EDIT

OK, let's break it down. You're clearly learning a lot, and trying lots of new stuff. That's great. It helps to have a solid idea both of your goals and of your tools, so let's talk about those.

Based on your comments, it's clear that you are intending to use IComparable for ordering and guaranteeing uniqueness in a form. Generally IComparable isn't used for uniqueness, but you have a 'business requirement' to use it, so...

Let's talk about the tools at hand. I think you just need to understand what IComparable means. It means that the class implementing it has a natural ordering, like numbers or (ahem) names in a list. Specifically, it guarantees three non-exceptional outcomes:

  1. this is "less than" the argument: return some number less than 0
  2. this is "greater than" the argument: return some number greater than 0
  3. this has the same order as the argument: return 0.

That's it.

Things that use the interface tend to be collections that sort items. They use that number to guide their sorting. The only thing they care about is if the number is less than, greater than, or equal to zero. The return number doesn't mean anything else, so returning -999 as you do isn't going to tell anybody anything useful. If whatever you have truly is not able to be compared, the right thing to do is to throw an exception.

So hopefully you have some idea how IComparable is used, let's talk about how it's usually implemented.

Have you heard of generics? It's a fundamental feature of .NET that will guide the compilation and execution of your code based on types. If an interface is generic, that means you can implement is multiple times, specifying a different type each time. There is a generic version of IComparable: System.IComparable<T>. If your class needs to compare strings, it should implement IComparable<string> as well as IComparable<Artist> or what-have-you. If you do so, your class will look something like this:

public class Artist : IComparable<string>, IComparable<Artist>
{
    // your code here

    public int Compare(string name)
    {
        // your code here
    }

    public int Compare(Artist artist)
    {
        // your code here
    }
}

If you are working with an older technology like Windows Forms that expects the non-generic IComparable interface, you can implement that, too, like so:

public int Compare(object obj)
{
    if (obj == null) return -1; // maybe you want to throw an exception instead?
    if (obj is string) return Compare((string) obj);
    if (obj is Artist) return Compare((Artist) obj);

    throw new ArgumentException("wtf, unexpected type");
}

Finally, why is your list of artists in the Album class? Think about where the check for uniqueness needs to happen. It happens when the user types in the form, right? Don't you think that the list belongs there, too?

查看更多
登录 后发表回答