gpt4 book ai didi

c# - 如何为一个列表中的不同类型的值设计工厂模式?

转载 作者:太空宇宙 更新时间:2023-11-03 12:57:33 24 4
gpt4 key购买 nike

我需要设计一个数据结构来保存不同类型的值( double 、字符串、日期时间等)。类型列表由用户动态创建。应根据该列表创建另一个值列表。然后这个值的“记录”将由 WCF 发送并存储在动态创建的数据库表中。我开始用 c# 设计这个解决方案。我的当前状态如下所示。我对我目前的解决方案不满意,尤其是工厂和枚举。有没有更好的方法来做正确的事情?

我的类型枚举:

public enum ValueType { Decimal, String, Boolean };

然后界面:

public interface IValueType
{
object Data { get; }
string ToString();
ValueType? Type { get; }
}

基类:

public abstract class ValueType<T> : IValueType
{
protected T _Value;

public ValueType(T value)
{
_Value = value;
}

public object Data
{
get { return _Value; }
}

public ValueType? Type
{
get { return null; }
}
public T Value { get; private set; }
public override string ToString()
{
return _Value.ToString();
}
}

实现之一:

public class DecimalValueType : ValueType<decimal>
{
public DecimalValueType( decimal val ) : base(val)
{}
public DecimalValueType(double val) : base((decimal)val)
{}
public DecimalValueType(int val) : base((decimal)val)
{}
}

然后工厂:

public static class ValueTypeFactory
{
private static Dictionary<ValueType, Type> dictValueType = new Dictionary<ValueType, Type>()
{
{ ValueType.Decimal, typeof(DecimalValueType) },
{ ValueType.String, typeof(StringValueType) },
{ ValueType.Boolean, typeof(BooleansValueType) }
};

private static Dictionary<Type, Type> dictSimple = new Dictionary<Type, Type>()
{
{ typeof(decimal), typeof(DecimalValueType) },
{ typeof(double), typeof(DecimalValueType) },
{ typeof(int), typeof(DecimalValueType) },
{ typeof(string), typeof(StringValueType) },
{ typeof(bool), typeof(BooleansValueType) }
};

public static IValueType MakeByValueType(ValueType type, params object[] initValues)
{
IValueType retObject = null;
if (dictValueType.ContainsKey(type) )
{
Type t = dictValueType[type];
retObject = (IValueType)Activator.CreateInstance(t,initValues);
}
return retObject;
}

public static IValueType MakeByType(params object[] initValues)
{
IValueType retObject = null;
if ( initValues.Length > 0 )
{
Type type = initValues[0].GetType();
if (dictSimple.ContainsKey(type))
{
Type t = dictSimple[type];
retObject = (IValueType)Activator.CreateInstance(t, initValues);

}
}
return retObject;
}
}

示例使用:

    List<IValueType> lista = new List<IValueType>();
lista.Add(new DecimalValueType(12));
lista.Add(new StringValueType("Test"));
lista.Add(new BooleansValueType(true));
lista.Add(ValueTypeFactory.MakeByValueType(ValueType.Decimal, 10.1));
lista.Add(ValueTypeFactory.MakeByType(5.12));
lista.Add(ValueTypeFactory.MakeByType("Test2"));

我很乐意接受任何建议。

最佳答案

这是一个更简单的解决方案,涵盖了您帖子中的用法并避免了 ValueType 子类噪声:

public abstract class ValueType
{
public enum Types { Decimal, String, Boolean };
public abstract object Data { get; }
public abstract Types Type { get; }
private ValueType() {}

protected class TypedValueType<T> : ValueType
{
private Types type;

public TypedValueType(T value, Types type) : base()
{
this.Value = value;
this.type = type;
}

public override object Data { get { return this.Value; } }
public override Types Type { get { return this.type; } }
public T Value { get; private set; }

public override string ToString()
{
return this.Value.ToString();
}

}

public static implicit operator ValueType(decimal value) { return new TypedValueType<decimal>(value, Types.Decimal); }
public static implicit operator ValueType(double value) { return new TypedValueType<decimal>((decimal)value, Types.Decimal); }
public static implicit operator ValueType(int value) { return new TypedValueType<decimal>((decimal)value, Types.Decimal); }
public static implicit operator ValueType(string value) { return new TypedValueType<string>(value, Types.String); }
public static implicit operator ValueType(bool value) { return new TypedValueType<bool>(value, Types.Boolean); }

}

示例用法:

public class Demo
{
public static void Main()
{
List<ValueType> lista = new List<ValueType>();
lista.Add(1);
lista.Add("Test");
lista.Add(true);
lista.Add(10.1);
lista.Add(5.12);
lista.Add("Test2");
foreach(var value in lista) Console.WriteLine(value.Data + " - " + value.Type.ToString());
Console.ReadKey();
}
}

由于您似乎想要限制可以包含的值的类型,因此嵌套的 TypedValueType 类被标记为 protected ,而 ValueType 构造函数被标记为私有(private)。隐式运算符用于提供“工厂”逻辑,用于为要转换的值生成适当类型的 TypeValueType 子类。

这是作为控制台应用程序执行的输出:

1 - Decimal
Test - String
True - Boolean
10.1 - Decimal
5.12 - Decimal
Test2 - String

关于c# - 如何为一个列表中的不同类型的值设计工厂模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33412246/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com