実行時に型がわかっているときに、dbの値を自分のオブジェクトにマップする方法は?

私のデータベースには次のようなテーブルがあります:

conditionID, conditionType, conditionValue

ConditionType is an enumeration with values like Integer, String, DateTime, etc.

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)
1
ジェネリックスを見てください。 msdn.microsoft.com/en-us/library /ms379564(v=vs.80).aspx
追加された 著者 Ash Burlaczenko,
あなたは私の最初の投稿のリンクを見てみる必要があります。データ型固有の機能のカプセル化は、AOMまたはType Objectパターンなどの単純化されたバリエーションです。
追加された 著者 Jeffrey,

5 答え

これは、適応オブジェクトモデルまたはタイプオブジェクトパターンを使用して簡単にモデル化することができます。それはあなたの状況にもかかわらず殺すかもしれない。

http://adaptiveobjectmodel.com/

http://www.cs.ox.ac.uk/jeremy .gibbons/dpa/typeobject.pdf

実行時にモデルを再構成したり、行動を追加/削除したり、ルールを定義したりすることができます。

2
追加された
面白い読書感謝。
追加された 著者 codecompleting,

あなたが言及したすべてのタイプは、 IComparable を実装しています。型はIComparableになり、CompareTo()メソッドを使用します。

bool GreaterThan(IComparable value, IComparable otherValue)
{
    return value.CompareTo(otherValue) > 0;
}
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;
    }
}
1
追加された
これは私のためにこれをより明確にすることができます、私はまた、整数のコレクションかどうかを確認することができます.GreaterThanメソッドなど
追加された 著者 codecompleting,
そのファクトリはint、stringまたはList を返しますか?うーん、私はまだそれを得ることはできません。
追加された 著者 codecompleting,
IValueType インタフェースを使用して、データベースに格納されるデータ型 "アーキタイプ"を定義することができます。 conditionType enumを取り込み、そのenum値の値とIValueTypeハンドラを使用してConditionValueのインスタンスを返すファクトリメソッドを用意します。
追加された 著者 Jeffrey,
    public enum ValueType
    {
        String = 0,
        Integer = 1,
        CustomDataType = 3
    }

    public interface IValueType : IComparer
    {
        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 { 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 _valueTypes = new Dictionary(); 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< 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(); } } 
1
追加された
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);
0
追加された
しかし、私は実行時にデータベースからデータを取得していますが、これがどのように機能するのかわかりません。
追加された 著者 codecompleting,
@MohamedAbed私は質問のデータベース列の例を与えたので、それらの列の値を持つ行を返します。
追加された 著者 codecompleting,
IntegerTypeなど、conditionTypeで定義されたデータ型を表すクラスを作成する必要があります。 IntegerTypeは整数値を比較する方法を知っています。また、値とデータ型ハンドラを受け入れる条件が必要です。
追加された 著者 Jeffrey,
どのようにして数値を比較することができますか?どのように "ここにあなたのコード"を書いていますか?私はあなたが "if(source> destination)"と書いてもそれがコンパイルされないと確信しています。
追加された 著者 Jeffrey,
どのようにデータベースからデータを取得するのですか?
追加された 著者 Mohamed Abed,
サンプルソリューションによる更新の回答
追加された 著者 Mohamed Abed,