我想做this question之类的事情,但它并没有像我期待的那样发挥作用。
我有一个对象属性及其类型的列表,一个未知对象,以及我想从对象中忽略的默认值类型列表。
public void GetOnlyNonDefault(object oObject, IgnoreValues ignoreValues)
{
//properties is set beforehand
for (int i = 0; i < properties.Count; i++)
{
object originalValue =
oObject
.GetType()
.GetProperty(properties[i].Name)
.GetValue(oObject, null);
//retrieving the default value I want to ignore for this property
object ignoreValue = ignoreValues.GetDefaultOf(properties[i]);
//Problem here
//This doesn't work
if (originalValue == ignoreValue) { continue; }
//This works for nearly everything BUT enums
if (ValueType.Equals(originalValue, ignoreValue)) { continue; }
}
}
我从here读取枚举'默认值为零,这就是当类型为枚举时我从GetDefaultOf
返回的内容。
如何通过上述代码中包含枚举的所有值类型的值进行比较?
编辑:可能相关,但我在oObject
课程中使用的枚举没有任何设置为0的值,它们都从1开始。
public enum UserStatus
{
Regular = 1, Manager = 2, Director = 3, Admin = 4
}
编辑²这是我正在尝试的代码的基本版本,给出了我遇到的结果:http://pastebin.com/rfJA9CGp
我无法真正更改枚举,因为这是代码的重点,我不知道运行时的对象是什么,也不知道它的属性,但是我想要找出与定义的默认值不同的任何值(类{ {1}}包含所有值类型的默认值。
当它是枚举时,我无法转换为IgnoreValues
,因为我忽略了在代码中实际定义了int
的枚举的情况,所以我正在寻找任何方式比较值。
答案 0 :(得分:4)
当运算符==
被赋予静态类型为object
的值时,它会进行原始参考比较。当放入变量类型object
时(以及从反射调用返回时),必须将值类型装箱,因此比较将始终为false,因为即使相等的值也会被装箱到两个不同的实例。
比较枚举的一种方法是将值拆分为int:
object foo1 = Foo.A;
object foo2 = Foo.A;
Console.WriteLine(foo1 == foo2); // False
Console.WriteLine((int) foo1 == (int) foo2); // True
当变量没有保存可以解包为int的内容时,此代码将失败,因此需要格外小心。特别是,如果枚举的底层类型不是int
(可能发生),它也会导致运行时异常。所以alernative是Enum.Equals
,它支持不同底层类型的枚举:
object foo = Foo.A;
if (foo.GetType().IsEnum)
Console.WriteLine(Enum.Equals(foo, your-default-value));
现在你已经展示了如何获得要比较的默认值,我知道问题是什么。您将整数 0
传递给Enum.Equals
。该方法以整数永远不等于枚举值的方式编写。获取默认值并不是很明显:
object foo = Foo.A;
object defaultEnumValue = Activator.CreateInstance(foo.GetType()))
Enum.Equals(foo, defaultEnumValue);
你可能已经注意到这是相对神秘的。这是因为当您的代码涉及处理所有可能的类型时,C#通常不是很好。这些类型是在编译时确定的,当然,当您编写检查任意对象的代码时,这是不可能的。