You need to implement something in your object that determines the order of the properties in order to establish a convention for the order of the parameters in the array.
One option is to create an Attribute to set the order of each property.
There are several advantages to using attributes: you are not subject to the fragility of the field order, you may have more properties in your class even if you do not want to value them from the array, etc.
In addition to the advantages, using attributes, you can define more metadata such as the format of the date received in the string, number of decimal places, required properties, validations, etc. And you can also create a graphical interface to show the updated layout of the expected layout (order and type of fields, data format, etc.) from these attribute metadata.
In this solution, I take advantage of the attributes to specialize the string conversion:
public class DadoAttribute : Attribute
{
public int Ordem { get; private set; }
public DadoAttribute(int ordem)
{
this.Ordem = ordem;
}
public virtual object ConverteValor(string valor, Type type)
{
return Convert.ChangeType(valor, type);
}
}
See that the attribute knows the conversion logic, so I can implement specific attributes for specific types, such as date:
public class DadoData : DadoAttribute
{
private String formatoData;
public DadoData(int ordem, String formatoData) : base(ordem)
{
this.formatoData = formatoData;
}
public override object ConverteValor(string valor, Type type)
{
return DateTime.ParseExact(valor, formatoData, null);
}
}
And then you can decorate each property by stating your order and eventually an attribute with special data conversion capability, like this:
public class Objeto
{
[Dado(0)]
public int _numero { get; set; }
[DadoData(1, "dd-MM-yyyy")]
public DateTime _data { get; set; }
[Dado(2)]
public string _palavra { get; set; }
[Dado(3)]
public decimal _decimal { get; set; }
}
Note that for the date property I have given you a specialized attribute.
Finally, you get the properties of your object by sorting them by the attribute you entered in each one, and arrow their respective value using the attribute conversion knowledge.
You can create a class to represent the property in order to specialize its logic of setting value in the object using the conversion knowledge contained in the attribute:
public delegate object ConverteValor(string valor, Type type);
public class Propriedade
{
private ConverteValor conversor;
private PropertyInfo property;
public Propriedade(PropertyInfo property, ConverteValor conversor)
{
this.conversor = conversor;
this.property = property;
}
public void SetValue(object objeto, string valor)
{
property.SetValue(objeto, conversor(valor, property.PropertyType));
}
}
And the logic to read get the properties and set the value on each looks like this:
public static class FabricaObjeto
{
public static Objeto Constroi(string[] dadosOrdenados)
{
var typeAtributoDado = typeof(DadoAttribute);
var propriedades =
from propriedade in typeof(Objeto).GetProperties()
where Attribute.IsDefined(propriedade, typeAtributoDado)
orderby
((DadoAttribute)Attribute.GetCustomAttribute(propriedade, typeAtributoDado)).Ordem
select new Propriedade (propriedade,
((DadoAttribute)Attribute.GetCustomAttribute(propriedade, typeAtributoDado))
.ConverteValor);
var objeto = new Objeto();
var indiceDado = 0;
foreach (var propriedade in propriedades)
{
propriedade.SetValue(objeto, dadosOrdenados[indiceDado]);
indiceDado++;
}
return objeto;
}
}
An example consumer code:
public class Program
{
public static void Main(string[] args)
{
var dadosOrdenados = new string[] { "1", "13-01-2015", "abc", "0.123" };
var objeto = FabricaObjeto.Constroi(dadosOrdenados);
Console.WriteLine(
string.Format("{0} - {1} - {2} - {3}"
, objeto._numero, objeto._data, objeto._palavra, objeto._decimal));
// saída: 1 - 13/01/2015 00:00:00 - abc - 0.123
}
}
This solution is useful, for example, to instantiate objects from delimited text file reading ( csv ). Sometimes we can not dictate the format of the file and our code will never escape needing to know the sequence of fields.
See working at .Net Fiddle .