我的数据库有一个表格如下:
conditionID, conditionType, conditionValue
ConditionType
是一个枚举,其值为Integer,String,DateTime等。
ConditionValue存储为字符串。
现在我想将这一行封装在一个类中,以便我可以在ConditionValue上执行比较,所以这就像EqualTo,GreaterThan,LessThan等。
目前我的设计不正确,因为我有像(otherValue
这样的方法是我正在比较的价值):
GreaterThan(string value, string otherValue);
GreaterThan(int value, int otherValue);
GreaterThan(DateTime value, DateTime otherValue);
我可以以某种方式创建一个包含此信息的ConditionValue类,以便我可以这样做:
GreaterThan(IConditionValue condition, IConditionValue otherValue)
答案 0 :(得分:2)
应该可以使用自适应对象模型或类型对象模式轻松建模。但是,对你的情况来说可能会过度杀戮。
http://adaptiveobjectmodel.com/
http://www.cs.ox.ac.uk/jeremy.gibbons/dpa/typeobject.pdf
它允许您在运行时重新配置模型,随意添加/删除行为,定义规则等。
答案 1 :(得分:1)
这是一个非常天真的例子。
public class ConditionValue
{
private object value;
private IValueType valueType;
public ConditionValue(object value, IValueType valueType)
{
this.value = value;
this.valueType = valueType;
}
public bool GreaterThan(ConditionValue cv)
{
return valueType.GreaterThan(this.value, cv.value);
}
}
public interface IValueType
{
bool GreaterThan(object left, object right);
}
public class IntegerType : IValueType
{
public bool GreaterThan(object left, object right)
{
return (int)left > (int)right;
}
}
答案 2 :(得分:1)
您提到的所有类型都实现了IComparable,因此您可以简单地假设类型是IComparable并使用CompareTo()方法。
bool GreaterThan(IComparable value, IComparable otherValue)
{
return value.CompareTo(otherValue) > 0;
}
答案 3 :(得分:1)
public enum ValueType
{
String = 0,
Integer = 1,
CustomDataType = 3
}
public interface IValueType : IComparer<object>
{
string ToString(object obj);
}
public class IntegerValueType : IValueType
{
public int Compare(object left, object right)
{
return ((int)left).CompareTo((int)right);
}
public string ToString(object obj)
{
return ((int)obj).ToString();
}
}
public class StringValueType : IValueType
{
public int Compare(object left, object right)
{
return ((string)left).CompareTo((string)right);
}
public string ToString(object obj)
{
return ((string)obj).ToString();
}
}
public class Value : IComparable<Value>
{
private object value;
private IValueType valueType;
public Value(object value, IValueType valueType)
{
this.value = value;
this.valueType = valueType;
}
public static implicit operator Value(string value)
{
return ValueFactory.Create(value, ValueType.String);
}
public int CompareTo(Value obj)
{
return this.valueType.Compare(this.value, obj.value);
}
public static bool operator <(Value left, Value right)
{
return left.CompareTo(right) == -1;
}
public static bool operator >(Value left, Value right)
{
return left.CompareTo(right) == 1;
}
public static bool operator ==(Value left, Value right)
{
return left.CompareTo(right) == 0;
}
public static bool operator !=(Value left, Value right)
{
return left.CompareTo(right) != 0;
}
public override string ToString()
{
return this.valueType.ToString(this.value);
}
}
public class ValueFactory
{
private static IDictionary<object, IValueType> _valueTypes =
new Dictionary<object, IValueType>();
static ValueFactory()
{
_valueTypes.Add(ValueType.String, new StringValueType());
_valueTypes.Add(ValueType.Integer, new IntegerValueType());
}
public static Value Create(object value, object valueType)
{
//
// This logic could be extended to find a ValueType that supports
// one of the types in the objects inheritance tree. This would
// also require creating an ObjectValueType, which would be a last
// resort in the case of the object type not being supported.
//
if (!_valueTypes.ContainsKey(valueType))
throw new ArgumentException("valueType is not supported");
return new Value(value, _valueTypes[valueType]);
}
}
class Program
{
static void Main(string[] args)
{
int x = 32;
int y = 16;
Value cx = ValueFactory.Create(x, ValueType.Integer);
Value cy = ValueFactory.Create(y, ValueType.Integer);
Console.WriteLine("cx = "+cx);
Console.WriteLine("cy = "+cy);
Console.WriteLine("x<y = {0}", cx < cy);
Console.WriteLine("x>y = {0}", cx > cy);
Console.WriteLine("x==y = {0}", cx == cy);
Console.WriteLine("x!=y = {0}", cx != cy);
Value name = ValueFactory.Create("Jeffrey Schultz", ValueType.String);
Console.WriteLine("{0} == You = {1}", name, name == "You");
Console.ReadLine();
}
}
答案 4 :(得分:0)
public interface IValueComparer
{
bool GreaterThan(string source, string destination);
bool LessThan(string source, string destination);
}
public class IntToIntComparer : IValueComparer
{
public bool GreaterThan(string source, string detination)
{
// better use TryParse and handle exception
return Int32.Parse(source) > Int32.Parse(detination);
}
public bool LessThan(string source, string detination)
{
// better use TryParse and handle exception
return Int32.Parse(source) < Int32.Parse(detination);
}
}
public class DateToDateComparer : IValueComparer
{
public bool GreaterThan(string source, string detination)
{
// better use TryParse and handle exception
return DateTime.Parse(source) > DateTime.Parse(detination);
}
public bool LessThan(string source, string detination)
{
// better use TryParse and handle exception
return DateTime.Parse(source) < DateTime.Parse(detination);
}
}
public class StringToStringComparer : IValueComparer
{
public bool GreaterThan(string source, string detination)
{
return source.Length > detination.Length;
}
public bool LessThan(string source, string detination)
{
return source.Length < detination.Length;
}
}
public class Condition
{
public int ID { get; set; }
public string Value { get; set; }
public string Type { get; set; }
public IValueComparer Comparer{get; set;}
public static string Integer { get { return "Integer"; } }
public static string String { get { return "String"; } }
public static string DateTime { get { return "DateTime"; } }
public static Condition CreateForType(string type)
{
if (type == Integer)
return new Condition { Type = type, Comparer = new IntToIntComparer() };
if (type == String)
return new Condition { Type = type, Comparer = new StringToStringComparer() };
if (type == DateTime)
return new Condition { Type = type, Comparer = new DateToDateComparer() };
return null;
}
public bool GreaterThan(Condition destination)
{
return Comparer.GreaterThan(Value, destination.Value);
}
public static bool operator >(Condition source, Condition destination)
{
return source.GreaterThan(destination);
}
public static bool operator <(Condition source, Condition destination)
{
return source.LessThan(destination);
}
public bool LessThan(Condition destination)
{
return Comparer.LessThan(Value, destination.Value);
}
}
var condition1 = Condition.CreateForType("Integer");
condition1.ID = 1;
condition1.Value = "5";
var condition2 = Condition.CreateForType("Integer");
condition2.ID = 2;
condition2.Value = "10";
bool result1 = condition1 > condition2;
bool result2 = condition1.LessThan(condition2);