-
September 22nd, 2016, 11:16 AM
#1
[RESOLVED] List<T>.Except() not working for me
In a nutshell, I have two generic lists of objects that I am using the .Except() extended method to return a list of exceptions into a new list. I remember getting this to work when I first researched it, but now that I am plugging it into the rest of the code, it returns the entire list instead of the exceptions.
The list is of these records:
Code:
using System;
using System.Configuration; // ADD REFERENCE: System.Configuration (StringValidator)
namespace OHS_RCIS.Report.OB_Adv
{
public class DenialRecord
{
private string inv_no;
private string cur_bal;
private string vendor;
private string adm_dt;
private string dschrg_dt;
private string crt_dt;
private string visit_ID;
// Exposed constructor
public DenialRecord
(
string Inv_No,
string Cur_Bal,
string Vendor,
string Adm_Dt,
string Dschrg_Dt,
string Crt_Dt,
string Visit_ID
)
{
this.inv_no = FieldValidate(Inv_No);
this.cur_bal = FieldValidate(Cur_Bal);
this.vendor = FieldValidate(Vendor);
this.adm_dt = FieldValidate(Adm_Dt);
this.dschrg_dt = FieldValidate(Dschrg_Dt);
this.crt_dt = FieldValidate(Crt_Dt);
this.visit_ID = FieldValidate(Visit_ID);
}
// Properties used by the recon files as fields
public string Inv_No { get { return inv_no; } set { inv_no = FieldValidate(Inv_No); } } // always a string of 7-4 - null if Mansfield/Marion
public string Cur_Bal { get { return cur_bal; } set { cur_bal = FieldValidate(Cur_Bal); } } // currency in spreadsheet
public string Vendor { get { return vendor; } set { vendor = FieldValidate(Vendor); } } // always a string
public string Adm_Dt { get { return adm_dt; } set { adm_dt = FieldValidate(Adm_Dt); } } // a date in spreadsheet
public string Dschrg_Dt { get { return dschrg_dt; } set { dschrg_dt = FieldValidate(Dschrg_Dt); } } // a date in spreadsheet
public string Crt_Dt { get { return dschrg_dt; } set { dschrg_dt = FieldValidate(Crt_Dt); } } // a date in spreadsheet
public string Visit_ID { get { return visit_ID; } set { visit_ID = FieldValidate(Visit_ID); } } // a number in spreadsheet - null if O'Bleness
// Current AdviCare files come in with the balance field containing $ - invoice has a hyphen - headers contain underscores -
// dates have a forward slash. No other special characters should be legal.
private string FieldValidate(string field)
{
string testVal = field;
StringValidator strValidator = new StringValidator(1, 40, "!@#%^&*()+={}[]|?:;");
try
{
strValidator.Validate(field);
}
catch (ArgumentException e)
{
Console.WriteLine("Error: {0}", e.ToString());
}
return field;
}
// Built-in comparer for list to list exceptions finding. Uses defined field in each record to compare.
public DenialRecord Except(DenialRecord other)
{
if (this.inv_no != other.inv_no)
{
return this;
}
else
{
return null;
}
}
}
}
The declaration of the lists is as follows:
Code:
// Declare lists to hold active inventory and to hold exceptions
List<DenialRecord> hospList = new List<DenialRecord>();
List<DenialRecord> vendList = new List<DenialRecord>();
List<DenialRecord> hospExcpt = new List<DenialRecord>();
List<DenialRecord> vendExcpt = new List<DenialRecord>();
The actual call to the Except method is here:
Code:
// Compare the lists each way for denials not in the other source
hospExcpt = hospList.Except(vendList).ToList();
vendExcpt = vendList.Except(hospList).ToList();
The class that builds the list is here:
Code:
// Load csv to List<T>
public List<DenialRecord> CsvToList(out int returnValue)
{
//int errorCode = 0;
using (TextFieldParser csvParser = new TextFieldParser(this.fullPath))
{
csvParser.TextFieldType = FieldType.Delimited;
csvParser.SetDelimiters(",");
csvParser.HasFieldsEnclosedInQuotes = true;
csvParser.TrimWhiteSpace = true;
returnValue = Error.ERROR_SUCCESS;
while (!csvParser.EndOfData)
{
try
{
string[] field = csvParser.ReadFields();
if (field.Length == columnCount)
{
DenialRecord dr = new DenialRecord(field[0], field[1], field[2], field[3], field[4], field[5], field[6]);
inputList.Add(dr);
}
}
catch (Exception e)
{
switch(e.HResult)
{
case 2:
returnValue = Error.ERROR_FILE_NOT_FOUND;
break;
case 3:
returnValue = Error.ERROR_PATH_NOT_FOUND;
break;
case 5:
returnValue = Error.ERROR_ACCESS_DENIED;
break;
case 11:
returnValue = Error.ERROR_FORMAT;
break;
case 167:
returnValue = Error.ERROR_MALFORMED_LINE;
break;
case unchecked((int)0x80131502):
returnValue = Error.ERROR_ARGUMENT_OUT_OF_RANGE;
break;
}
DenialRecord dr = new DenialRecord("bad data", "bad data", "bad data", "bad data", "bad data", "bad data", "bad data");
inputList.Add(dr);
}
}
}
return inputList;
}
}
}
The field each list is using for the comparison is a string. So far, I have not seen a reason in looking at the List<T> class, its methods or the classes it inherits from. There has got to be a reason I am just not seeing. Has anyone thought of what I could have overlooked?
EDIT: I found the solution here on CodeGuru. Mutant_Fruit explained it much more clearly than the places I had been looking. Essentially, even though you roll your own .Except() method in your class, when comparing objects or non-numbers, you have to build a hash of the field and override the Equals() function to do the correct compare required by the Exclude() function. Below is the working code:
Code:
// Built-in comparer for list to list exceptions finding. Uses defined field in each record to compare.
public DenialRecord Except(DenialRecord other)
{
if (this.inv_no != other.inv_no)
{
return this;
}
else
{
return null;
}
}
// Except() requires overriding the Equals() and GetHashCode() to know how to compare
public override bool Equals(object other)
{
if (other is DenialRecord)
return ((DenialRecord)other).inv_no == inv_no;
else
return ((DenialRecord)other).inv_no == inv_no;
}
public override int GetHashCode()
{
return inv_no.GetHashCode();
}
Last edited by Jim Snyder; September 22nd, 2016 at 02:48 PM.
Reason: Found solution
.NET Framework Version 4.5.50938; Visual Studio Professional 2013 Version 12.0.21005.1 REL
"Having power is nice, having a lot of power is very nice, having too much power is just about right!"
-
September 25th, 2016, 03:35 PM
#2
Re: List<T>.Except() not working for me
Jim, took the liberty of marking the thread resolved since you indicated you found the solution.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|