比较 T 类型的两个 System.Enum
Compare two System.Enum of type T
我现在非常接近理解泛型(我认为)。
但是,只是认为 System.Enum 作为泛型类型实现起来并不容易。
我有这个 class:
public class Button<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
public TEnum Identifier {
get;
private set; //Set in the ctor
}
}
和
public abstract class AbstractInputDevice<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
private List<Button<TEnum>> _buttons = new List<Button<TEnum>>();
public Button<TEnum> GetButton(TEnum Identifier){
foreach(Button<TEnum> button in _buttons){
if(button.Identifier == Identifier) //<- compiler throws
return button;
}
Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
return null;
}
}
InputDevice 可能看起来像这样:
public class Keyboard : AbstractInputDevice<KeyCode> {
private void Useless(){
Button<KeyCode> = GetButton(KeyCode.A);
}
}
编译器在此处抛出编译错误:
if(button.Identifier == Identifier) //In AbstractInputDevice above
我相信我无法比较这两个 TEnum,因为它们实际上并不知道是枚举。
因此没有可用的比较方法。
我使用了这个资源:
Create Generic method constraining T to an Enum
感谢任何更好的解决方案或修复。
(但我想保留 Enum 条目作为 GetButton(EnumEntry)
的参数)
您正在尝试对值类型(结构)执行引用比较,请使用 Equals
代替:
public Button<TEnum> GetButton(TEnum Identifier) {
var button = _buttons
.Where(b => EqualityComparer<TEnum>.Default.Equals(b.Identifier, Identifier))
.FirstOrDefault();
if (button == null)
Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
return button;
}
无法执行button.Identifier == Identifier
语句,因为结构不存在==
运算符。在 class 上,它会执行参考比较。
正如@JeppeStigNielsen 在他的 中指出的那样,为防止装箱相等比较,最好使用 EqualityComparer<TEnum>.Default.Equals
方法。
而不是不可能
button.Identifier == Identifier
你应该使用
EqualityComparer<TEnum>.Default.Equals(button.Identifier, Identifier)
这避免了将值装入 object
框(或 IComparable
框)。
我现在非常接近理解泛型(我认为)。
但是,只是认为 System.Enum 作为泛型类型实现起来并不容易。
我有这个 class:
public class Button<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
public TEnum Identifier {
get;
private set; //Set in the ctor
}
}
和
public abstract class AbstractInputDevice<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
private List<Button<TEnum>> _buttons = new List<Button<TEnum>>();
public Button<TEnum> GetButton(TEnum Identifier){
foreach(Button<TEnum> button in _buttons){
if(button.Identifier == Identifier) //<- compiler throws
return button;
}
Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
return null;
}
}
InputDevice 可能看起来像这样:
public class Keyboard : AbstractInputDevice<KeyCode> {
private void Useless(){
Button<KeyCode> = GetButton(KeyCode.A);
}
}
编译器在此处抛出编译错误:
if(button.Identifier == Identifier) //In AbstractInputDevice above
我相信我无法比较这两个 TEnum,因为它们实际上并不知道是枚举。
因此没有可用的比较方法。
我使用了这个资源:
Create Generic method constraining T to an Enum
感谢任何更好的解决方案或修复。
(但我想保留 Enum 条目作为 GetButton(EnumEntry)
的参数)
您正在尝试对值类型(结构)执行引用比较,请使用 Equals
代替:
public Button<TEnum> GetButton(TEnum Identifier) {
var button = _buttons
.Where(b => EqualityComparer<TEnum>.Default.Equals(b.Identifier, Identifier))
.FirstOrDefault();
if (button == null)
Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
return button;
}
无法执行button.Identifier == Identifier
语句,因为结构不存在==
运算符。在 class 上,它会执行参考比较。
正如@JeppeStigNielsen 在他的 EqualityComparer<TEnum>.Default.Equals
方法。
而不是不可能
button.Identifier == Identifier
你应该使用
EqualityComparer<TEnum>.Default.Equals(button.Identifier, Identifier)
这避免了将值装入 object
框(或 IComparable
框)。