Harold
Harold

Reputation: 1166

Unable to compare generic values

How come if I run this code:

namespace TestCode
{
    public class EnumList<TEnum>
    {
        private IList<TEnum> _list;


        public EnumList()
        {
            _list = new List<TEnum>();
        }

        public void Add(TEnum val)
        {
            _list.Add(val);
        }

        public int Get(TEnum val)
        {
            return (int)(from one in _list
                         where one == val
                         select one).First();
        }
    }
}

Gives me an error to do with not being able to convert type TEnum to type TestCode.TEnum?

(This is 'paraphrased' by the way as my actual code is at home and I'm at work)

Edit: Removed the <TEnum> from the constructor as that's not the main problem

Upvotes: 1

Views: 169

Answers (4)

andygjp
andygjp

Reputation: 2464

I would change the return type of the Get method, then you can just cast the result to int:

    public class EnumList<TEnum> where TEnum:struct, IComparable
    {
        private IList<TEnum> _list;

        public EnumList()
        {
            _list = new List<TEnum>();
        }

        public void Add(TEnum val)
        {
            _list.Add(val);
        }

        public TEnum Get(TEnum val)
        {
            return _list.Single(l => l.CompareTo(val) == 0);
        }
    }

    public class MyClass
    {
        public void MyMethod()
        {
            var list = new EnumList<DayOfWeek>();
            var value = (int)list.Get(DayOfWeek.Wednesday);
        }
    }

Upvotes: 0

larsmoa
larsmoa

Reputation: 12932

There's two problems with the Get()-function:

  1. one == val isn't a valid statement as TEnum isn't bound. Try using Equals(one, val) instead (I'm assuming that TEnum will be an enum-type)
  2. Casting the result to int is invalid as there is no way of knowing if there is a conversion from TEnum to int.

You could try

public int Get(TEnum val)
{            
    var result = (from one in _list
                 where Equals(one, val)
                 select one).First();
    return (Int32) Convert.ChangeType(result, typeof(Int32));
} 

However, this is dangerous territory and will no way be typesafe.

Upvotes: 0

ZoolWay
ZoolWay

Reputation: 5505

Ommit the <TEnum> part in your constructor because in this case it thinks you might be able to assign a different TEnum on the constructor and on the class itself. Funny that it does not complain about both having the same name.

Upvotes: 0

Tormod
Tormod

Reputation: 4573

You should put a constraint on the TEnum type. What do you mean when writing "=="? ReferenceEquals? IComparable.Equals? Memberwise equals?

Upvotes: 1

Related Questions