I've got this class DNS_Log
that has four properties. I've created a list of these objects that I am trying to filter though for only distinct occurrences. (When the list is being populated, there are a lot of repeats)
Here's the listing being populated:
dnsLogs.Add( new DNS_Log { Destination = destination,
Source_IP = sourceIp,
Domain_Controller = domainController,
DateTime = datetime });
Here's my attempt at trying to filter out the distinct ones only:
dnsLogs = dnsLogs.Distinct().ToList();
Why does this not work? Do I need some linq expression in the distinct param? I want to compare the the objects as a whole on their properties. Is there any easier way of doing this?
P.S. I've played around with making a custom IEqualityComparer<DNS_Log>
that seems to work fine but I don't know how to implement it in this scenario.
You've got several options:
DNS_Log
IEquatable<T>
NOTE! In all the code below, the equality check assumes that the ==
operator knows how to deal with each type. That is certainly true for the DateTime member (assuming it is of type DateTime as well), but I obviously cannot guarantee that the others will work. If the Destination member holds a type for which the ==
operator has not been defined, this is likely to do the wrong thing. Since you haven't posted your own code for this comparer implementation, it's impossible to know what to do here.
IEquatable<T>
public class DNS_Log : IEquatable<DNS_Log>
{
public bool Equals(DNS_Log other)
{
if (other == null)
return false;
return (other.Destination == Destination
&& other.Source_IP == Source_IP
&& other.Domain_Controller == Domain_Controller
&& other.DateTime == DateTime);
}
public override int GetHashCode()
{
int hash = 23;
hash = hash * 59 + (Destination == null ? 0 : Destination.GetHashCode());
hash = hash * 59 + (Source_IP == null ? 0 : Source_IP.GetHashCode());
hash = hash * 59 + (Domain_Controller == null ? 0 : Domain_Controller.GetHashCode());
hash = hash * 59 + DateTime.GetHashCode();
return hash;
}
}
public class DNS_Log
{
public override bool Equals(object obj)
{
if (obj == null) return false;
var other = obj as DNS_Log;
if (other == null) return false;
... rest the same as above
IEqualityComparer<T>
Lastly, you can provide an IEqualityComparer<T> when calling Distinct
:
dnsLogs = dnsLogs.Distinct(new DNS_LogEqualityComparer()).ToList();
public class DNS_LogEqualityComparer : IEqualityComparer<DNS_Log>
{
public int GetHashCode(DNS_Log obj)
{
int hash = 23;
hash = hash * 59 + (obj.Destination == null ? 0 : obj.Destination.GetHashCode());
hash = hash * 59 + (obj.Source_IP == null ? 0 : obj.Source_IP.GetHashCode());
hash = hash * 59 + (obj.Domain_Controller == null ? 0 : obj.Domain_Controller.GetHashCode());
hash = hash * 59 + obj.DateTime.GetHashCode();
return hash;
}
public bool Equals(DNS_Log x, DNS_Log y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null) return false;
return (x.Destination == y.Destination
&& x.Source_IP == y.Source_IP
&& .Domain_Controller == y.Domain_Controller
&& x.DateTime == y.DateTime);
}
}
You basically have three options:
IEqualityComparer<DNS_Log>
when calling Distinct
(something like dnsLogs.Distinct(myEqualityComparerInstance).ToList();
DNS_Log
implement IEquatable<DNS_Log>
Equals
and GetHashCode
on DNS_Log
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With