ConcurrentBag FirstOrDefault NullCheck throws - c#

I've got a Problem at my null check .
if (element == null)
throws
Object reference not set to an instance of an object.
Why can a simple null check fail at this Point? When i make a breakpoint at this Position, element has the value "null", but throws the exception anyway.
PS: At this Point, are no additional Threads active.
internal static ConcurrentBag<Node_Library> AddFileDetail(
this ConcurrentBag<Node_Library> list,
FileDetails file , Node<Node_Application> app)
{
var element = list.FirstOrDefault(x => file.Equals(x));
if (element == null)
{
list.Add(new Node_Library(file, app));
}
else
{
if (!element.ApplicationNodes.Contains(app))
{
element.AddNode(app);
}
}
return list;
}
EDIT: file is not null, the list is empty but not null
EDIT2: Operator and FileDetail details
public class FileDetails
{
internal string FileName { get; private set; }
internal string Name { get; private set;}
internal string Endung { get; private set; }
internal string Version { get; private set; }
internal string Produkt { get; private set; }
internal string ProduktVersion { get; private set; }
internal FileTyp Filetyp { get; private set; }
internal string Pfad { get; private set; }
public static bool operator==(FileDetails file1, Node_Library library)
{
return
file1.Version == library.Version &&
file1.Produkt == library.Produkt &&
file1.ProduktVersion == library.ProduktVersion &&
file1.FileName == library.FileName;
}
public static bool operator !=(FileDetails file1, Node_Library library)
{
return
!(file1.Version == library.Version &&
file1.Produkt == library.Produkt &&
file1.ProduktVersion == library.ProduktVersion &&
file1.FileName == library.FileName);
}
public static bool operator ==(FileDetails file1, FileDetails file2)
{
if (
file1.FileName == file2.FileName &&
file1.Produkt == file2.Produkt &&
file1.ProduktVersion == file2.ProduktVersion &&
file1.Version == file2.Version)
return true;
return false;
}
public static bool operator !=(FileDetails file1, FileDetails file2)
{
if (
file1.Name == file2.Name &&
file1.Produkt == file2.Produkt &&
file1.ProduktVersion == file2.ProduktVersion &&
file1.Version == file2.Version)
return false;
return true;
}
internal bool Equals(Node_Library file2)
{
if (file2 == null)
{
return false;
}
return (
Name == file2.Name &&
Produkt == file2.Produkt &&
ProduktVersion == file2.ProduktVersion &&
Version == file2.Version);
}
//More Stuff
}
EDIT3:
I used a breakpoint in my equal overload, but it never triggered... So the problem is maybe the FirstOrDefault?
finally:
Operatoroverload was faulty. Fixed it. Ty a lot.

The problem lies in your operators:
public static bool operator==(FileDetails file1, Node_Library library)
{
return
file1.Version == library.Version &&
file1.Produkt == library.Produkt &&
file1.ProduktVersion == library.ProduktVersion &&
file1.FileName == library.FileName;
}
When you compare an instance to null it's trying to access the properties Version, Produkt, ProduktVersion and FileName from a null instance, hence the NullReferenceException.
So, answering to your initial question "Why can a simple null check fail at this Point?", it's because there's nothing simple about that null check once you override the operators. =D
To solve it, you can add a null check on file2:
public static bool operator ==(FileDetails file1, FileDetails file2)
{
if (file2 != null &&
file1.FileName == file2.FileName &&
file1.Produkt == file2.Produkt &&
file1.ProduktVersion == file2.ProduktVersion &&
file1.Version == file2.Version)
return true;
return false;
}

The problem may be the previous line:
var element = list.FirstOrDefault(x => file.Equals(x));
The file parameter is probably null.
EDIT: If file is not null, then the FileDetails.Equals method can be the culprit.

Related

How to check whether all two objects' properties are equal, including derived ones?

Let's say I have these three classes:
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int IdNumber { get; set; }
public string Address { get; set; }
// Constructor and methods.
}
class Employee : Person
{
public byte SalaryPerHour { get; set; }
public byte HoursPerMonth { get; set; }
// Constructor and methods.
}
class Seller : Employee
{
public short SalesGoal { get; set; }
public bool MetSaleGoleLastYear { get; set; }
// Constructor and methods.
}
I would implement IEquatable<T> like this:
public bool Equals(Person other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address;
}
public bool Equals(Employee other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address
&& SalaryPerHour == other.SalaryPerHour
&& HoursPerMonth == other.HoursPerMonth;
}
public bool Equals(Seller other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address
&& SalaryPerHour == other.SalaryPerHour
&& HoursPerMonth == other.HoursPerMonth
&& SalesGoal == other.SalesGoal
&& MetSaleGoleLastYear == other.MetSaleGoleLastYear;
}
Now, as you can see, the more a class is down the inheritance chain, the more properties I need to check. If for example, I inherit from a class someone else written, I also need to see the class code to find all of its properties, so I could use them to check value equality. It sounds strange to me. Isn't there a better way of doing this?
Use base. Much shorter.
public bool Equals(Seller other)
{
if (other == null) return false;
return base.Equals(other)
&& SalesGoal == other.SalaryPerHour;
&& MetSaleGoleLastYear == other.HoursPerMonth;
}
In addition to John Wu's answer, here is the corrected complete solution :
public bool Equals(Person other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address;
}
public bool Equals(Employee other)
{
if (other == null) return false;
return base.Equals(other)
&& SalaryPerHour == other.SalaryPerHour // ; removed
&& HoursPerMonth == other.HoursPerMonth;
}
public bool Equals(Seller other)
{
if (other == null) return false;
return base.Equals(other)
&& SalesGoal == other.SalesGoal // SalaryPerHour;
&& MetSaleGoleLastYear == other.MetSaleGoleLastYear; //HoursPerMonth;
}

Implementing equality for 2d lines

I have simple class defining 2d line:
public class Line {
public double X1 { get; set; }
public double Y1 { get; set; }
public double X2 { get; set; }
public double Y2 { get; set; }
}
My primary goal is to get different lines from List using .Distinct(). In my case two lines are equal if theirs coordinates are equal regardless direction (line 1,2 -> 3,4 equals to 3,4 -> 1,2). I going to implement Equals like:
public override bool Equals(object obj) {
if (obj as Line == null) { return false; }
var second = (Line)obj;
if (this.X1 != second.X1 && this.X1 != second.X2) { return false; }
if (this.Y1 != second.Y1 && this.Y1 != second.Y2) { return false; }
if (this.X2 != second.X2 && this.X2 != second.X1) { return false; }
if (this.Y2 != second.Y2 && this.Y2 != second.Y1) { return false; }
return true;
}
but I have no idea how to implement GetHashCode (as I understand it's necessary to make it in case of using Distinct())
This becomes a bit easier if you first define a Point, then define your Line in terms of 2 Points.
Now, to calculate a reliable (but unaffected by direction) hash of a Line, make sure you order your points consistently when calculating the hash.
Putting this all together into a complete implementation (which also covers operator == and !=):
public class Point
{
public double X { get; set; }
public double Y { get; set; }
protected bool Equals(Point other)
{
return X.Equals(other.X) && Y.Equals(other.Y);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Point) obj);
}
public override int GetHashCode()
{
unchecked
{
return (X.GetHashCode()*397) + Y.GetHashCode();
}
}
public static bool operator ==(Point left, Point right)
{
return Equals(left, right);
}
public static bool operator !=(Point left, Point right)
{
return !Equals(left, right);
}
}
public class Line
{
public Point Point1 { get; set; }
public Point Point2 { get; set; }
protected bool Equals(Line other)
{
return Equals(Point1, other.Point1) && Equals(Point2, other.Point2)
|| Equals(Point1, other.Point2) && Equals(Point2, other.Point1);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Line) obj);
}
public override int GetHashCode()
{
unchecked
{
var orderedPoints =
new[] {Point1, Point2}.OrderBy(p => p != null ? p.X : 0)
.ThenBy(p => p != null ? p.Y : 0).ToList();
var p1 = orderedPoints[0];
var p2 = orderedPoints[1];
return ((p1 != null ? p1.GetHashCode() : 0)*397)
+ (p2 != null ? p2.GetHashCode() : 0);
}
}
public static bool operator ==(Line left, Line right)
{
return Equals(left, right);
}
public static bool operator !=(Line left, Line right)
{
return !Equals(left, right);
}
}

Comparing (specific) object properties in c#

Building upon this answer for comparing objects in C#
Comparing object properties in c#
Knowing this is a complex topic, I wanted to handle a few more specific structures.
While this code will match properties if they are simple value types such as this object:
public class BasicStuff
{
public int anInt { get; set; }
public bool aBool { get; set; }
}
But as soon as it gets any more complex, this code fails.
So what I would like to do is make it a bit more usable for nested objects of the above, such as:
public class NestedStuff
{
public BasicStuff theBasic { get; set; }
}
Any array of the above, such as:
public class ArrayStuff
{
public BasicStuff[] theBasicArray { get; set; }
}
And finally any combination of the above:
public class AllTheStuff
{
public int anInt { get; set; }
public bool aBool { get; set; }
public BasicStuff theBasic { get; set; }
public BasicStuff[] theBasicArray { get; set; }
}
So what I came up with was the following:
public static bool AllPublicPropertiesEqual<T>(T AObj, T BObj, params string[] ignore) where T : class
{
if (AObj != null && BObj != null)
{
Type type = typeof(T);
List<string> ignoreList = new List<string>(ignore);
foreach (PropertyInfo pInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!ignoreList.Contains(pInfo.Name))
{
if (pInfo.PropertyType.IsArray)
{
object AValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
string t = AValue.GetType().ToString();
if (!AllPublicPropertiesEqual<object>(AValue, BValue))
return false;
}
else if (!pInfo.PropertyType.IsValueType && !pInfo.PropertyType.IsPrimitive && !pInfo.PropertyType.IsEnum && pInfo.PropertyType != typeof(string))
//else if (Convert.GetTypeCode(pInfo.PropertyType) == TypeCode.Object)
{
object AValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (!AllPublicPropertiesEqual<object>(BValue, AValue))
return false;
}
else
{
object selfValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object toValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue)))
return false;
}
}
}
return true;
}
return AObj == BObj;
}
Only this fails because when recursively calling AllPublicPropertiesEqual, I need to pass the specific values type rather than just a generic object type.
But I dont know how to do this.... Any ideas are greatly appreciated...
Your method does not have to be generic. You can change the beginning of the method to:
public static bool AllPublicPropertiesEqual(object AObj, object BObj, params string[] ignore)
{
if (AObj != null && BObj != null)
{
Type type = AObj.GetType();
if (BObj.GetType() != type)
throw new Exception("Objects should be of the same type");
....
}
....
}
Well first thing what is that you should create Interface for those classes because from what I see you can combine those classes but all of them will have the same properties. Second option is create some Base abstract class with those properties and inherit from it. It is up to you what you choose.
Than create in this Base class or Interface Equals functions where you will equal directly the shared properties it is much easier and I think more efficient :-)
public abstract class BaseStaff {
public int anInt { get; set; }
public bool aBool { get; set; }
public abstract bool Equals(BaseStaff anotherStaff);
}
Then you can use this class and create your BasicStaff class and AllTheStaff class too in BasicStaff implement Equals method like this.
public override bool Equals(BaseStaff staff) {
this.anInt == staff.anInt &&
this.aBool == staff.aBool;
}
In AllTheStaff u can than override this method like this
public override bool Equals(BaseStaff staff) {
bool baseEquals = base.Equals(staff);
bool basicStaffEquals = this.BasicStaff.Equals(staff);
return baseEquals || basicStaffEquals;
}
This is just core idea and maybe I dont understand you well what you really want to achieve but hope it helps you :)
tested Solution
public static bool AllPublicPropertiesEqual<T>(T AObj, T BObj, params string[] ignore) where T : class
{
if (AObj != null && BObj != null)
{
Type type = typeof(T);
List<string> ignoreList = new List<string>(ignore);
foreach (PropertyInfo pInfo in type.GetCType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!ignoreList.Contains(pInfo.Name))
{
if (pInfo.PropertyType.IsArray)
{
object aElementValues = (type.GetProperty(pInfo.Name).GetValue(AObj, null));
object bElementValues = (type.GetProperty(pInfo.Name).GetValue(BObj, null));
if (aElementValues != null && bElementValues != null)
{
List<object> AListValues = new List<object>();
List<object> BListValues = new List<object>();
foreach (var v in (IEnumerable)aElementValues)
AListValues.Add(v);
foreach (var v in (IEnumerable)bElementValues)
BListValues.Add(v);
if (AListValues.Count == BListValues.Count)
{
object[] aArray = AListValues.ToArray();
object[] bArray = BListValues.ToArray();
for (int i = 0; i < aArray.Length; i++)
{
if (!AllPublicPropertiesEqual(aArray[i], bArray[i]))
return false;
}
}
else
return false;
}
else if ((aElementValues == null) != (bElementValues == null))
return false;
}
else if (!pInfo.PropertyType.IsValueType && !pInfo.PropertyType.IsPrimitive && !pInfo.PropertyType.IsEnum && pInfo.PropertyType != typeof(string))
//else if (Convert.GetTypeCode(pInfo.PropertyType) == TypeCode.Object)
{
object AObjectValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BObjectValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (!AllPublicPropertiesEqual(BObjectValue, AObjectValue))
return false;
}
else
{
object aValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object bValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (aValue != bValue && (aValue == null || !aValue.Equals(bValue)))
return false;
}
}
}
return true;
}
return AObj == BObj;
}
}

Multiple User Roles in Authorize

I have a controller which can be accessed by user having admin privileges or nurse. Then on separate action I can do more strict if I want to. Right now what I have is something like this
[AuthorizeUser(UserRole = "Admin", OrganizationType = "Institution")]
It works fine. But I would something like
[AuthorizeUser(UserRole = "Admin,Nurse", OrganizationType = "Institution")]
AuthorizeUser is custom made authorization
public class AuthorizeUser : AuthorizeAttribute
{
public string UserRole { get; set; }
public string OrganizationType { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
return false;
}
return CheckOrganizationType
.checkRole(this.UserRole, this.OrganizationType, Auth.CurrentUser);
}
}
public static bool checkRole(String role, String organizationType, User user)
{
RolesType rt = null;
OrganizationType ot = null;
foreach (UserRoles ur in user.GetUserRoles())
{
rt = RolesType.Get(ur.organizationTypeId,ur.roleTypeId);
ot = OrganizationType.Get(ur.organizationTypeId, "1");
}
if (rt != null && rt.Name == role && ot != null && ot.Name == organizationType)
{
return true;
}
else
{
return false;
}
}
and then check if the current user has any of the defined roles. How can this be done? Any idea?
You have just to change this statement:
if (rt != null && rt.Name == role && ot != null && ot.Name == organizationType)
with this:
if (rt != null && role.Contains(rt.Name) && ot != null && ot.Name == organizationType)

GetHashCode for the object with several data members

public class MyClass
{
public string x;
public string y;
}
public class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
public int GetHashCode(MyClass myobj)
{
if(myObj == null)
{
return base.GetHashCode();
}
if (myObj.x != null && myObj.y != null)
{
return myObj.x.GetGashCode()^myObj.y.GetGashCode();
}
}
}
what should be the implementation if myObj.x or/and myObj.y are nulls
The only requirement for a hash code is that two objects that are considered equal share the same hash code.
You can, for example, use 0 for null properties
public int GetHashCode(MyClass myobj)
{
if(myObj == null)
{
return base.GetHashCode();
}
return (myObj.x != null ? myObj.x.GetGashCode() : 0) ^ (myObj.y != null ? myObj.y.GetGashCode() : 0)
}

Categories

Resources