能否限定泛型参数必须是enum?泛型参数是enum时,怎么做枚举对象的==操作?

phommy 2013-09-26 09:04:30
下边的两种比较方式都会提示运算符“==”无法应用于“T”和“T”类型的操作数
加了where T:struct 或 where T:enum也不行(后一种语法就不对)
问题如题。。。


enum MyEnum
{
}

class MyClass<T>
{
T value;

public bool EqualTo(T obj)
{
return (T)value == (T)obj; //error
return value == obj; //error
//强制转换成int也不行,用object.Equals的结果又不是我想要的。。。
}
}


...全文
690 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2013-09-28
  • 打赏
  • 举报
回复
好吧,ls有人提了。
threenewbee 2013-09-28
  • 打赏
  • 举报
回复
引用 5 楼 phommy 的回复:
[quote=引用 4 楼 caozhy 的回复:] 你想做什么,比较引用是否相等,值是否相等,其中的某些字段相等,调用这个对象的==运算符,还是什么。
我想既然已经确定T是值类型,能不能就按值类型比较?进一步的,有没有办法告诉编译器我的T就是int枚举、就给我按数字(而不是一般的struct)进行比较?

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var m = new MyClass<MyEnum>(MyEnum.b);
            var s = m.EqualTo(MyEnum.b);
        }
    }

    enum MyEnum
    {
        a,
        b
    }

    class MyClass<T> where T : struct
    {
        T value;

        public MyClass(T value) { this.value = value; }

        public bool EqualTo(T obj)
        {
            //return (T)value == (T)obj; //编译错误
            //return value == obj; //编译错误
            //return (int)value == (int)obj;  //编译错误
            return obj.Equals(value); //结果对,但有装箱
        }
    }
}
[/quote] 你限定ICompareable就是了。 int double string等等都实现了它。
moonwrite 2013-09-27
  • 打赏
  • 举报
回复
我是这样的~ class MyClass<T> where T : struct { //反射 判断是否是枚举类型 Type t.IsEnum }
qldsrx 2013-09-27
  • 打赏
  • 举报
回复
你如果是要避免装箱拆箱,可以使用这个方法: return Comparer<T>.Default.Compare(value, obj) == 0; 不过个人认为这里面装箱拆箱的性能损失是可以忽略的。 最后吐槽下3楼,基础不够扎实,虽然枚举有个Enum类型是class,但是枚举值本身是值类型,非引用类型,因此限定struct。而事实上IL层面上对枚举值的转换处理也只有装箱拆箱动作,完全符合值类型的说法。
youzelin 2013-09-27
  • 打赏
  • 举报
回复
直接上代码:

class MyClass<T> where T : struct
{
    public T Value { get; private set; }
    public MyClass(T value)
    {
        Value = value;
    }

    public bool EqualTo(T obj)
    {
        return obj.GetType().IsEnum ? Value.Equals(obj) : false;
    }
}
static void Main(string[] args)
{
    MyClass<StringComparison> myObj = new MyClass<StringComparison>(StringComparison.CurrentCulture);
    Console.WriteLine(myObj.EqualTo(StringComparison.CurrentCultureIgnoreCase));
    Console.ReadKey();
}
phommy 2013-09-27
  • 打赏
  • 举报
回复
引用 4 楼 caozhy 的回复:
你想做什么,比较引用是否相等,值是否相等,其中的某些字段相等,调用这个对象的==运算符,还是什么。
我想既然已经确定T是值类型,能不能就按值类型比较?进一步的,有没有办法告诉编译器我的T就是int枚举、就给我按数字(而不是一般的struct)进行比较?

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var m = new MyClass<MyEnum>(MyEnum.b);
            var s = m.EqualTo(MyEnum.b);
        }
    }

    enum MyEnum
    {
        a,
        b
    }

    class MyClass<T> where T : struct
    {
        T value;

        public MyClass(T value) { this.value = value; }

        public bool EqualTo(T obj)
        {
            //return (T)value == (T)obj; //编译错误
            //return value == obj; //编译错误
            //return (int)value == (int)obj;  //编译错误
            return obj.Equals(value); //结果对,但有装箱
        }
    }
}
  • 打赏
  • 举报
回复
引用 7 楼 qldsrx 的回复:
你如果是要避免装箱拆箱,可以使用这个方法: return Comparer<T>.Default.Compare(value, obj) == 0; 不过个人认为这里面装箱拆箱的性能损失是可以忽略的。 最后吐槽下3楼,基础不够扎实,虽然枚举有个Enum类型是class,但是枚举值本身是值类型,非引用类型,因此限定struct。而事实上IL层面上对枚举值的转换处理也只有装箱拆箱动作,完全符合值类型的说法。
原来如此,那我限定class还能传入枚举值是怎么回事…
phommy 2013-09-27
  • 打赏
  • 举报
回复
引用 7 楼 qldsrx 的回复:
你如果是要避免装箱拆箱,可以使用这个方法: return Comparer<T>.Default.Compare(value, obj) == 0; 不过个人认为这里面装箱拆箱的性能损失是可以忽略的。 最后吐槽下3楼,基础不够扎实,虽然枚举有个Enum类型是class,但是枚举值本身是值类型,非引用类型,因此限定struct。而事实上IL层面上对枚举值的转换处理也只有装箱拆箱动作,完全符合值类型的说法。
谢谢~ 我会写个代码测试两种方式的性能差别 顺便我也吐槽下ms,为什么enum能默认实现IComparable,但不给默认实现IComparable<>。。。
threenewbee 2013-09-26
  • 打赏
  • 举报
回复
你想做什么,比较引用是否相等,值是否相等,其中的某些字段相等,调用这个对象的==运算符,还是什么。
  • 打赏
  • 举报
回复
两个T类型可以用做比较 枚举是个引用类型,不是值类型,继承与Enum基类,所以要限制就限制到class 下面这段临时敲的代码毫无意义。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        public enum Myenum
        { 
           one,
           two,
            three,
        }
        static void Main(string[] args)
        {
            Person<Enum> p = new Person<Enum>();
            p.value = Myenum.one;
            Console.WriteLine(p.EqluasTo(Myenum.one));
            Console.ReadKey();
            
        }
    }
    public class Person<T>where T:class
    {
        public T value;
        public T Value { get { return this.value; } }

        public bool EqluasTo(T outher)
        {
            if (Value.ToString() == outher.ToString())
                return true;
            return false;
        }
      
    }
}
种草德鲁伊 2013-09-26
  • 打赏
  • 举报
回复
还有就是先判断引用是否相同,再判断类型是否相同,再用Equals方法比较
种草德鲁伊 2013-09-26
  • 打赏
  • 举报
回复
不能,最多限定struct

110,529

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧