Determining the correct data type from a name
I have created an application that allows users to capture information for entities based on a pre-defined template, which I create through a web interface.
So for instance I create a template and call it "Customer Template" with several properties like First Name, Last Name, Email address and I associate a "data type" to each property, which does not strictly map to a开发者_开发百科 strongly typed type.
When the user then creates a new "Customer" a html form is generated with the appropriate properties / fields, which the user can provide and save.
The data types are called "Plain Text" or "Number" or "Currency" but do not map to a data type. What would be the best approach to associate a "number" to a strongly typed int, for instance, so that when I do operations on it that it is the correct type?
The number of "types" that the users will use are finite, maybe less than 10. Would I run into problems with a switch statement? Or is there another way?
I use c#.
I would use custom attributes to identify the CLR type mapped to your Form Types as such:
public enum FieldDataTypes
{
[FormTypeMetadata(typeof(string))]
PlainText = 0,
[FormTypeMetadata(typeof(int))]
Number = 1,
[FormTypeMetadata(typeof(decimal))]
Currency = 2
}
public class FormTypeMetadataAttribute : Attribute
{
private readonly Type _baseType = typeof(object);
public FormTypeMetadataAttribute(Type baseType)
{
if (baseType == null) throw new ArgumentNullException("baseType");
_baseType = baseType;
}
public Type BaseType { get { return _baseType; } }
}
// your 'FieldData' implementation would look like this...
public class FieldData
{
public FieldDataTypes FieldType { get; set; }
public object Value { get; set; }
}
You can retrieve the FieldDataTypes' attribute using reflection.
If you're using custom types for all of your data types, why not define each as a class that derives from a common abstract parent class like FormDataType
. The parent class could expose some useful methods such as primitive data type association, while derived classes can handle validation, formatting, etc.
Here's a simple example where the parent class is generic. A separate interface definition is included for cases where the generic type argument T
varies or is unknown:
public interface IFormDataType
{
object Value { get; }
Type PrimitiveType { get; }
string Format();
}
public abstract class FormDataType<T> : IFormDataType
{
object IFormDataType.Value { get { return Value; } }
public Type PrimitiveType { get { return typeof(T); } }
public T Value { get; private set; }
public FormDataType(T value)
{
Value = value;
}
public abstract string Format();
public override string ToString()
{
return Format();
}
}
public class Currency : FormDataType<decimal>
{
public Currency(decimal value)
: base(value)
{
//perform any validation if necessary
}
public override string Format()
{
return Value.ToString("C");
}
public static Currency Parse(string s)
{
return new Currency(decimal.Parse(s, NumberStyles.Currency));
}
}
To improve these classes, you might implement Equals
, GetHashCode
, IConvertible
, serialization, validation, etc.
精彩评论