枚举取决于类型T.

时间:2009-09-02 03:19:34

标签: c# generics enums

我有一个泛型类,需要根据定义的类型限制枚举:

public enum ConditionOperatorsString { None, Like, Equal }
public enum ConditionOperatorsDate { None, Equal, BeforeThan, AfterThan }
public class Condition<T>
{
  public T Value { get; set; }
  public ConditionOperatorsString Operator { get; set; }
  public Condition(T Value, ConditionOperatorsString Operator)
  {
    this.Value = Value;
    this.Operator = Operator;
  }
}

现在的问题是我希望运算符类型依赖于T,所以:

Condition<string> CStr= new Condition<string>(string.Empty, ConditionOperatorsString.None)
Condition<DateTime> CStr= new Condition<DateTime>(DateTime.Now, ConditionOperatorsDate.None)

如何为此定义类Condition?我想到了一个接口,但枚举不会从接口继承。

5 个答案:

答案 0 :(得分:1)

没有好的方法可以在你的构造函数中执行你想要做的事情:

if (typeof(T) == typeof(string) && 
    typeof(Operator) != typeof(ConditionOperatorsString))
{ 
    throw new Exception("Invalid conditionoperators value);
}

这真的不是很有用,因为你必须提前知道T的所有不同可能性。

可以做什么,是这样的:

public abstract class ComparableBase<T,K>
{
    public T Value { get; protected set; }
    public K ConditionOperator { get; protected set; }
    // public abstract bool IsMatch(T other); // Is this required?

    protected ComparableBase(T value, K op)
    {
        this.Value = value;
        this.ConditionOperator = op;
    }
}

public enum ComparableOperator { None, Equal, Less, Greater }

public enum LikeOrEqualOperator { None, Like, Equal }

public class ComparableCondition<T> : ComparableBase<T,ComparableOperator>
{
    public ComparableCondition(T value, ComparableOperator op):base(value, op)
    {
    }
}

public class LikeOrEqualCondition<T> : ComparableBase<T, LikeOrEqualOperator>
{
    public LikeOrEqualCondition(T value, LikeOrEqualOperator op):base(value, op)
    {
    }
}

然后你可以声明

var condition1 = new LikeOrEqualCondition<string>("hi", LikeOrEqualOperator.Equal);

您需要IsMatch吗?或者这是显示所选过滤器,而不实际实现它。

如果你这样做,事情会变得更加复杂......

答案 1 :(得分:0)

枚举类型是否只是另一个通用参数,例如

public enum ConditionOperatorsString { None, Like, Equal }
public enum ConditionOperatorsDate { None, Equal, BeforeThan, AfterThan }
public class Condition<T, TEnum>
{
  public T Value { get; set; }
  public TEnum Operator { get; set; }
  public Condition(T Value, TEnum Operator)
  {
    this.Value = Value;
    this.Operator = Operator;
  }
}

可能需要更多信息,而不是100%确定这是如何实际适应将使用它的代码

答案 2 :(得分:0)

您应该将枚举类型包含为模板参数。

public class Condition<TValue, TOperator> 
{
    public TValue Value { get; private set; }
    public TOperator Operator { get; private set; }

    private Condition(TValue val, TOperator op)
    {
        Value = val;
        Operator = op;
    }
}

能够添加where TOperator : Enum会很高兴,但我很确定编译器不允许这样做。

答案 3 :(得分:0)

感谢您的回答。

我想避免拥有多个课程,但显然无法完成。基于silky的最后评论,我得到了与nader类似的解决方案。 不是最优的,但它确实限制了枚举,con是客户必须知道有n个类:

public abstract class ConditionBase<T, E>
{
  public T Value { get; set; }
  public E Operator { get; set; }
  protected ConditionBase(T Value, E Operator)
  {
    this.Value = Value;
    this.Operator = Operator;
  }
}

public enum ConditionOperatorsString { None, Like, Equal }
public class ConditionString : ConditionBase<string, ConditionOperatorsString>
{
  public ConditionString(String Value, ConditionOperatorsString Operator) : base(Value, Operator) { }
}
public enum ConditionOperatorsDate { None, Like, BeforeThan, AfterThan }
public class ConditionDate : ConditionBase<DateTime?, ConditionOperatorsDate>
{
  public ConditionDate(DateTime? Value, ConditionOperatorsDate Operator) : base(Value, Operator) { }
}

客户使用:

  ConditionString StrCond = new ConditionString(string.Empty, ConditionOperatorsString.None);
  ConditionDate DateCond = new ConditionDate(DateTime.MinValue, ConditionOperatorsDate.None);

我希望能够从客户端使用类似的东西:

  ConditionGeneric StrCond = new ConditionGeneric(string.Empty, ConditionOperatorsString.None);
  ConditionGeneric DateCond = new ConditionGeneric(DateTime.MinValue, ConditionOperatorsDate.None);
  ConditionGeneric InvalidStrCond = new ConditionGeneric(string.Empty, ConditionOperatorsDate.None);
  ConditionGeneric InvalidDateCond = new ConditionGeneric(DateTime.MinValue, ConditionOperatorsString.None);

答案 4 :(得分:-1)

如果你创造了自己的领域

public ValueType Operator { get; set; }

它会起作用,但我不确定这是不是你想要的......

- 编辑

无论如何,你还想做什么? C#有运算符重载,所以也许这可能是有用的,而不是?