2

I'm trying to create a public property, which could either be of type long or Guid. Is it possible with generics? e.g. something like

public virtual T where T: long or Gui Id { get; set; }
Ruslan
  • 9,927
  • 15
  • 55
  • 89

5 Answers5

5

Is it possible with generics?

It is not possible, but you can work around by using use implicit operator to support both long and Guid, sample code:

internal class YourId
{
    public long LongId { get; private set; }
     public Guid GuidId { get; private set; }

    public YourId(long longValue)
    {
        LongId = longValue;
    }

    public YourId(Guid guidValue)
    {
        GuidId = guidValue;
    }

    public static implicit operator long(YourId yourId)
    {
        return yourId.LongId;
    }

    public static  implicit operator YourId(long value)
    {
        return new YourId(value);
    }

       public static implicit operator Guid(YourId yourId)
    {
        return yourId.GuidId;
    }

    public static  implicit operator YourId(Guid value)
    {
        return new YourId(value);
    }
}

Now you can use:

YourId id1 = Guid.NewGuid();
YourId id2 = long.MaxValue;
cuongle
  • 74,024
  • 28
  • 151
  • 206
1

Nope, this isn't possible. If you only have two possible types, just write the class twice, putting as much common code in a common base class as possible?

Rawling
  • 49,248
  • 7
  • 89
  • 127
1

No, that's not possible. There is no such constraint. Here's a list of possible constraints.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
1

No this is not possible, you have to chose an same parent class, or you should write your own implementation of a class which can store both.

Something like:

class LongOrGuid
{
     private Guid _guid;
     private long _long;
     private bool _isGuid = true;

     public LongOrGuid(Guid g)
     {
          _guid = g;
          _isGuid = true;
     }

     public LongOrGuid(long l)
     {
          _long = l;
          _isGuid = false;
     }

     public long Long
     {
          get
          {
               if(_isGuid)
               {
                    throw new NotSupportedException("This is a guid");
               }
               return _long;
          }
     }

     public Guid Guid
     {
          get
          {
               if(!_isGuid)
               {
                    throw new NotSupportedException("This is a long");
               }
               return _guid;
          }
     }

     public bool IsGuid
     {
          get
          {
               return _isGuid;
          }
     }
}
SynerCoder
  • 12,493
  • 4
  • 47
  • 78
1

A property can't be generic like that. Maybe you can make the class containing the property generic instead?

You can't restrict to long or Guid. You could say:

class ClassContainingYourProperty<T> where T : struct, IFormattable, IComparable<T>, IEquatable<T>
{
  static ClassContainingYourProperty() // do type check in static constructor
  {
    var t = typeof(T);
    if (t != typeof(long) && t != typeof(Guid))
      throw new NotSupportedException("T cannot be " + t);
  }

  public virtual T YourProperty { get; set; }
}
Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181