Existe-t-il un moyen dans c # de parcourir les propriétés d'une classe?
Fondamentalement, j'ai une classe qui contient un grand nombre de propriétés (elle contient essentiellement les résultats d'une requête de base de données volumineuse) . J'ai besoin de générer ces résultats sous forme de fichier CSV. Il est donc nécessaire d'ajouter chaque valeur à une chaîne.
La méthode évidente consiste à ajouter manuellement chaque valeur à une chaîne, mais existe-t-il un moyen de boucler efficacement sur l'objet de résultats et d'ajouter la valeur de chaque propriété à son tour?
Sûr; vous pouvez le faire de plusieurs façons; en commençant par la réflexion (remarque, ceci est lent - OK pour des quantités modérées de données):
var props = objectType.GetProperties();
foreach(object obj in data) {
foreach(var prop in props) {
object value = prop.GetValue(obj, null); // against prop.Name
}
}
Toutefois; pour des volumes de données plus importants, il serait intéressant de rendre cela plus efficace; Par exemple, ici, j'utilise l'API Expression
pour pré-compiler un délégué qui ressemble à chaque propriété. L'avantage ici est qu'aucune réflexion n'est effectuée par ligne (cela devrait être beaucoup plus rapide pour de gros volumes de données):
static void Main()
{
var data = new[] {
new { Foo = 123, Bar = "abc" },
new { Foo = 456, Bar = "def" },
new { Foo = 789, Bar = "ghi" },
};
string s = Write(data);
}
static Expression StringBuilderAppend(Expression instance, Expression arg)
{
var method = typeof(StringBuilder).GetMethod("Append", new Type[] { arg.Type });
return Expression.Call(instance, method, arg);
}
static string Write<T>(IEnumerable<T> data)
{
var props = typeof(T).GetProperties();
var sb = Expression.Parameter(typeof(StringBuilder));
var obj = Expression.Parameter(typeof(T));
Expression body = sb;
foreach(var prop in props) {
body = StringBuilderAppend(body, Expression.Property(obj, prop));
body = StringBuilderAppend(body, Expression.Constant("="));
body = StringBuilderAppend(body, Expression.Constant(prop.Name));
body = StringBuilderAppend(body, Expression.Constant("; "));
}
body = Expression.Call(body, "AppendLine", Type.EmptyTypes);
var lambda = Expression.Lambda<Func<StringBuilder, T, StringBuilder>>(body, sb, obj);
var func = lambda.Compile();
var result = new StringBuilder();
foreach (T row in data)
{
func(result, row);
}
return result.ToString();
}
foreach (PropertyInfo prop in typeof(MyType).GetProperties())
{
Console.WriteLine(prop.Name);
}
J'ai essayé diverses recommandations sur cette page, je ne pouvais tout à fait en faire fonctionner aucune. J'ai commencé avec la première réponse (vous remarquerez que mes variables portent le même nom), et je l'ai simplement analysée par moi-même. C’est ce que j’ai dû faire - espérons que cela pourra aider quelqu'un d’autre.
var prop = emp.GetType().GetProperties(); //emp is my class
foreach (var props in prop)
{
var variable = props.GetMethod;
empHolder.Add(variable.Invoke(emp, null).ToString()); //empHolder = ArrayList
}
*** Je devrais mentionner que cela ne fonctionnera que si vous utilisez get; set; propriétés (publiques).
Vous pouvez faire une liste des propriétés de l'objet
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
Et utilisez ensuite un foreach pour naviguer dans la liste.
foreach (var property in properties)
{
here's code...
}
var csv = string.Join(",",myObj
.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(p => p.GetValue(myObj, null).ToString())
.ToArray());
Utilisez quelque chose comme
StringBuilder csv = String.Empty;
PropertyInfo[] ps this.GetType().GetProperties();
foreach (PropertyInfo p in ps)
{
csv.Append(p.GetValue(this, null);
csv.Append(",");
}
string notes = "";
Type typModelCls = trans.GetType(); //trans is the object name
foreach (PropertyInfo prop in typModelCls.GetProperties())
{
notes = notes + prop.Name + " : " + prop.GetValue(trans, null) + ",";
}
notes = notes.Substring(0, notes.Length - 1);
Nous pouvons ensuite écrire la chaîne de notes sous forme de colonne dans la table de journal ou dans un fichier. Vous devez utiliser System.Reflection pour utiliser PropertyInfo
obtenir des valeurs de propriétés à partir d'un objet de classe simple ....
class Person
{
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
var person1 = new Person
{
Name = "John",
Surname = "Doe",
Age = 47
};
var props = typeof(Person).GetProperties();
int counter = 0;
while (counter != props.Count())
{
Console.WriteLine(props.ElementAt(counter).GetValue(person1, null));
counter++;
}
}
}
voici comment boucler les propriétés de vb.net, le même concept que c #, il suffit de traduire la syntaxe:
Dim properties() As PropertyInfo = Me.GetType.GetProperties(BindingFlags.Public Or BindingFlags.Instance)
If properties IsNot Nothing AndAlso properties.Length > 0 Then
properties = properties.Except(baseProperties)
For Each p As PropertyInfo In properties
If p.Name <> "" Then
p.SetValue(Me, Date.Now, Nothing) 'user p.GetValue in your case
End If
Next
End If
Boucle sur les propriétés
Type t = typeof(MyClass);
foreach (var property in t.GetProperties())
{
}
string target = "RECEIPT_FOOTER_MESSAGE_LINE" + index + "Column";
PropertyInfo prop = xEdipV2Dataset.ReceiptDataInfo.GetType().GetProperty(target);
Type t = xEdipV2Dataset.ReceiptDataInfo.RECEIPT_FOOTER_MESSAGE_LINE10Column.GetType();
prop.SetValue(t, fline, null);
Attentat pour cela: l'objet cible doit être paramétrable