I got tired of dealing with properties and fields separately so I made a VariableInfo
strategy pattern to handle both without having to know what type it is. You feed the context a FieldInfo
or a PropertyInfo
and it makes a VariableInfo
out of it. I've also made VariableInfo
extend MemberInfo
. There are extensions for pulling a type's fields and properties and returning all of them as VariableInfo
objects (GetAllVariables()
). Here is a part of the class definition (check this github repo for complete definition of all classes I describe here)
public class VariableInfo : MemberInfo
{
//InfoParent has 2 children. One for fields and one for properties.
private InfoParent variable;
public VariableInfo(PropertyInfo pi)
{
variable = new VariableProperty(pi);
}
public VariableInfo(FieldInfo fi)
{
variable = new VariableField(fi);
}
//mi is the internally stored PropertyInfo or FieldInfo. With this set, Attribute.IsDefined does not work for properties (solved in previous question linked below)
//NOTE: when I talk about "PASSTHROUGH", this next commented line is active and the other MemberType is commented out.
//public override MemberTypes MemberType => variable.mi.MemberType;
//updated to this to fix the Attribute.IsDefined bug:
public override MemberTypes MemberType => MemberTypes.Custom;
...
}
In my previous question, Ivan figured out that in order to get Attribute.IsDefined
to work, the MemberType
in the VariableInfo
class needed to point to MemberTypes.Custom
. This avoids a cast that doesn't work in the BCL source code. Unfortunately, that had a very unexpected result... Linq queries no longer work. Doing a variables.Distinct()
doesn't remove duplicates. When stepping into the Distinct, you can see the hash codes for the duplicate variables MATCH, but it doesn't remove the duplicates. When I revert the change, it works again.
Visual (Code is in the linked repo) -
The GetAllVariables_CUSTOM()
uses the MemberType
set to custom and the passthrough one points to the internal PropertyInfo
/FieldInfo
object.
So the questions are...
- Why?
- Is there a way around this without breaking Attribute.IsDefined?
NOTE: The GetAllVariables()
method iterates up the base types to make sure it gets everything. That's why there are duplicates. Doing a GetProperties()
on a PropertyInfo
, even with the BindingFlags
set to include both public and non-public variables, will excludes private variables in parent classes. Same thing goes for fields.
I got tired of dealing with properties and fields separately so I made a VariableInfo
strategy pattern to handle both without having to know what type it is. You feed the context a FieldInfo
or a PropertyInfo
and it makes a VariableInfo
out of it. I've also made VariableInfo
extend MemberInfo
. There are extensions for pulling a type's fields and properties and returning all of them as VariableInfo
objects (GetAllVariables()
). Here is a part of the class definition (check this github repo for complete definition of all classes I describe here)
public class VariableInfo : MemberInfo
{
//InfoParent has 2 children. One for fields and one for properties.
private InfoParent variable;
public VariableInfo(PropertyInfo pi)
{
variable = new VariableProperty(pi);
}
public VariableInfo(FieldInfo fi)
{
variable = new VariableField(fi);
}
//mi is the internally stored PropertyInfo or FieldInfo. With this set, Attribute.IsDefined does not work for properties (solved in previous question linked below)
//NOTE: when I talk about "PASSTHROUGH", this next commented line is active and the other MemberType is commented out.
//public override MemberTypes MemberType => variable.mi.MemberType;
//updated to this to fix the Attribute.IsDefined bug:
public override MemberTypes MemberType => MemberTypes.Custom;
...
}
In my previous question, Ivan figured out that in order to get Attribute.IsDefined
to work, the MemberType
in the VariableInfo
class needed to point to MemberTypes.Custom
. This avoids a cast that doesn't work in the BCL source code. Unfortunately, that had a very unexpected result... Linq queries no longer work. Doing a variables.Distinct()
doesn't remove duplicates. When stepping into the Distinct, you can see the hash codes for the duplicate variables MATCH, but it doesn't remove the duplicates. When I revert the change, it works again.
Visual (Code is in the linked repo) -
The GetAllVariables_CUSTOM()
uses the MemberType
set to custom and the passthrough one points to the internal PropertyInfo
/FieldInfo
object.
So the questions are...
- Why?
- Is there a way around this without breaking Attribute.IsDefined?
NOTE: The GetAllVariables()
method iterates up the base types to make sure it gets everything. That's why there are duplicates. Doing a GetProperties()
on a PropertyInfo
, even with the BindingFlags
set to include both public and non-public variables, will excludes private variables in parent classes. Same thing goes for fields.
1 Answer
Reset to default 1Because of the following code:
if (variable.MemberType != other.MemberType)
return false;
variable.MemberType
is the actual member type, but other.MemberType
is always MemberTypes.Custom
, so this comparison always fails.
Perhaps what you want is variable.MemberType != other.variable.MemberType
?
Equals
implementation is wrong. Put a breakpoint in yourEquals
and step into it and see what it is doing. – mjwills Commented Mar 18 at 2:35