【问题标题】:Generic property with two possible types具有两种可能类型的通用属性
【发布时间】:2012-09-12 15:08:51
【问题描述】:

我正在尝试创建一个公共属性,它的类型可以是longGuid。泛型可以吗?例如像

public virtual T where T: long or Gui Id { get; set; }

【问题讨论】:

  • 这是不可能的。你想达到什么目的?也许我们能找到解决办法。
  • 你可以,但是你必须在 c# 中创建一个联合类型,因为没有提供开箱即用的类型。见stackoverflow.com/questions/3151702/…

标签: c# .net generics


【解决方案1】:

泛型可以吗?

这是不可能的,但您可以通过使用implicit operator 来支持longGuid,示例代码:

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);
    }
}

现在你可以使用了:

YourId id1 = Guid.NewGuid();
YourId id2 = long.MaxValue;

【讨论】:

    【解决方案2】:

    属性不能像那样是通用的。也许您可以改为将包含该属性的类设为泛型?

    您不能限制为longGuid。你可以说:

    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; }
    }
    

    【讨论】:

      【解决方案3】:

      不,这是不可能的,你必须选择同一个父类,或者你应该编写一个可以存储两者的类的自己的实现。

      类似:

      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;
                }
           }
      }
      

      【讨论】:

        【解决方案4】:

        不,这是不可能的。没有这样的约束。这是list of possible constraints

        【讨论】:

          【解决方案5】:

          不,这是不可能的。如果你只有两种可能的类型,就写两次类,把尽可能多的通用代码放在一个通用的基类中?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-03-27
            • 2015-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多