-2

I cant seem to find a way not to add objects into my list that are the same, I tried .Contains but I just did not get it to work, any other workarounds? I believe I must use a if statement, and have the creation of the object in the else, but how do I do in the if statement?

public Form1()
    {
        InitializeComponent();
    }
    private const string filnamn = "kontakter.bin";
    Kontakter kontakt;
    private List<Kontakter> kontakter;


    private void buttonLagra_Click(object sender, EventArgs e)
    {
            Kontakter nyKontakt = new Kontakter();
            {
                nyKontakt.Telefonnr = textBoxTelefonnr.Text;
                nyKontakt.Namn = textBoxNamn.Text;
            }

            kontakter.Add(nyKontakt);
            listBox1.DataSource = null;
            listBox1.DataSource = kontakter;
            BinaryFormatter bf = new BinaryFormatter();
            FileStream fs = new FileStream(filnamn, FileMode.OpenOrCreate, FileAccess.Write);
            bf.Serialize(fs, kontakter);
            fs.Close();
        }
  • 1
    The default comparison for reference type is to *only* compare the reference address, not compare the actual content. So you will need to implement custom comparisons to compare two `Kontakter`. For example, by implementing [IEquatable](https://msdn.microsoft.com/en-us/library/ms131187%28v=vs.110%29.aspx). But if you need a list with only unique entries, you might want to consider `HashSet` rather than `List`. – Matt Burland Jan 29 '15 at 14:20
  • 2
    If `Kontakter` overrides `Equals`+`GetHashCode` or you create a custom `IEqualityComparer` you can use a `HashSet` which doesn't allow duplicates and returns `false` from `Add`. – Tim Schmelter Jan 29 '15 at 14:20
  • Check [Remove duplicates from a List in C#](http://stackoverflow.com/q/47752/1488067). – Lou Jan 29 '15 at 14:21

6 Answers6

5

List.Contains(o) checks whether the object o references is in the list. This isn't the case, as you just did o = new {...}.

You want to check whether an object containing the same properties is present in the list:

if (!kontakter.Any(k => k.Telefonnr == textBoxTelefonnr.Text
                     && k.Namn == textBoxNamn.Text))
{
    kontakter.Add(new {...});
}

You can also let your Kontakter implement IEquatable<Kontakter>, so .Contains() does do what you expect it to. See .Contains on a list of custom class objects for an implementation.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • well here you don't have to make a mistake to get a downvote :) – Selman Genç Jan 29 '15 at 14:32
  • not everybody has access to linq, hence why i downvoted. should have commented too, sorry. – FlemGrem Jan 29 '15 at 14:37
  • 3
    @AaronH: Since when that is a reason to downvote. OP didn't specify he does want it to work with a specific version of .NET so everyonce is free to answer. – Patrick Hofman Jan 29 '15 at 14:39
  • why confuse code reading with linq when the code is far more readable with fully expanded code (especially when learning) – FlemGrem Jan 29 '15 at 15:00
  • @AaronH I don't think a `foreach` with a helper variable and a `break` and an `if (temp == null) { ... }` check is more readable, as there's a lot more going on than in `.Any()`. – CodeCaster Jan 29 '15 at 15:04
  • no need to think about it then. life's too short. peace. – FlemGrem Jan 29 '15 at 16:07
0

List.Contains wouldn't work because you need to implement an equals method in the class definition. At the end, try List<Kontakter> distinct = kontakter.Distinct().ToList(); Be sure to include System.Linq!

0

In your case you have to override the definition of Equals on Kontakter and then define the logic of equal objects. Without overriding .NET compare the object type which is always different because we do the New key word.Sample code on MSDN https://msdn.microsoft.com/en-us/library/bsc2ak47%28v=vs.110%29.aspx

            public class Kontakter {
             public bool override Equals(Object obj) {    
                       var castedObj  = (Kontakter)obj;
                       return castedObj.PropertyOne == this.ProperyOne &&  castedObj.Property2 == this.Property2
                   }
             }
Devesh
  • 4,500
  • 1
  • 17
  • 28
0

Solution 1 with Linq's Any:

if(!kontakte.Any(k => k.Telefonnummer != myKontakt.Telefonnummer 
                    && k.Name != myKontakt.Name))
    kontakte.Add(nyKontakt);

Solution 2 implement Equals on Kontakt class:

public class Kontakt
{  
   public override bool Equals(Object obj) 
   {
      Kontakt other = obj as Kontakt;

      if (other == null) 
         return false;    

      return other.Telefonnummer == this.Telefonnummer 
            && other.Name == this.Name;
   }
}

Then you can use

if(!kontakte.Contains(myKontakt))
    kontakte.Add(myKontakt);
BoeseB
  • 695
  • 4
  • 17
0

you need to check if exists with a key, for example the name:

    private void buttonLagra_Click(object sender, EventArgs e)
    {
        Kontakter nyKontakt = new Kontakter();
        {
            nyKontakt.Telefonnr = textBoxTelefonnr.Text;
            nyKontakt.Namn = textBoxNamn.Text;
        }

        bool exists = false;
        foreach (var item in kontackter)
        {
            if (item.Namn == nyKontakt.Namn)
            {
                exists = true;
                break;
            }
        }

        if (!exists)
        {
            kontakter.Add(nyKontakt);
            listBox1.DataSource = null;
            listBox1.DataSource = kontakter;
            BinaryFormatter bf = new BinaryFormatter();
            FileStream fs = new FileStream(filnamn, FileMode.OpenOrCreate, FileAccess.Write);
            bf.Serialize(fs, kontakter);
            fs.Close();
        }
    }
ghiboz
  • 7,863
  • 21
  • 85
  • 131
0

Use a foreach and check the current textbox entry is not your list before adding a new item to your list..

 bool found = false;

 foreach(Kontakter thisKontakt in kontakter)
 {
     if ((thisKontakt.Telefonnr == textBoxTelefonnr.Text) && (thisKontakt.Namn == textBoxNamn.Text))
     {
         found = true;
         break;
     }
 }

 if(!found)
 {
     kontakter.Add(thisKontakt);
 }
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
FlemGrem
  • 814
  • 4
  • 9
  • edited to find item in loop and set item outside of loop as per PH's suggestion. Thanks for your input PH, very kind. – FlemGrem Jan 29 '15 at 16:05