我们有一个这样的(测试)课程:
class Animal
{
public string AnimalName { get; set; }
public string AnimalType { get; set; }
public int AnimalAgeInMonths { get; set; }
}
...以及类的对象(或引用):
Animal animal = new Animal();
animal.AnimalName = null; // No name yet
animal.AnimalType = "Sheep";
animal.AnimalAgeInMonths = 7;
所以我需要一个返回
System.Collections.Generic.List<(string[], string[], string[])>
的方法。第一个字符串数组表示所有属性的名称(即 AnimalName
、AnimalType
等),第二个数组 - 值(即 null、Sheep
等),第三个数组 - 数据类型,例如:
System.Int32
对于int
System.Single
对于float
System.String
对于string
(可以使用
typeof
关键字生成)。
所以总的来说,我需要这样的方法:
public List<(string[], string[], string[])> GetClassPropertyInfo(object Class)
可以这样调用:
GetClassPropertyInfo(animal);
我尝试过这个(第四次尝试):
using System;
using System.Reflection;
using System.Collections.Generic;
namespace TestAttempt
{
public class Animal
{
public string AnimalName { get; set; }
public string AnimalType { get; set; }
public int AnimalAgeInMonths { get; set; }
}
public class Program
{
static void Main()
{
Animal a = new Animal();
a.AnimalName = "";
a.AnimalType = "Sheep";
a.AnimalAgeInMonths = 7;
List<(string[], string[], string[])> types = new Program().GetClassPropertyInfo(a, typeof(Animal));
foreach (var Iteration in types)
{
for (int i = 0; i < Iteration.Item1.Length; i++)
{
Console.WriteLine($"{Iteration.Item3[i]} {Iteration.Item1[i]} = {Iteration.Item2[i]}");
}
}
}
private List<(string[], string[], string[])> GetClassPropertyInfo(object Class, Type _Class)
{
var @return = new List<(string[], string[], string[])>();
List<string> propertyNames = new List<string>();
List<string> propertyTypes = new List<string>();
List<string> propertyValues = new List<string>();
// https://stackoverflow.com/questions/737151/how-to-get-the-list-of-properties-of-a-class
foreach (var prop in Class.GetType().GetProperties())
{
propertyNames.Add(Convert.ToString(prop.Name));
propertyValues.Add(Convert.ToString(prop.GetValue(Class, null)));
}
// System.Reflection.FieldInfo
// See: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.fieldinfo?view=net-7.0
FieldInfo[] fi = _Class.GetFields(BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.Public);
for (int i = 0; i < fi.Length; i++)
propertyTypes.Add(Convert.ToString(fi[i].FieldType));
@return.Add((propertyNames.ToArray(), propertyValues.ToArray(), propertyTypes.ToArray()));
return @return;
}
}
}
它可以工作,但当数组是属性时则不行。
致以诚挚的问候,
-winscripter。
以下将获取每个属性的名称、类型和值(作为字符串) - 您可以使用它作为起点。然后,您可以将名称、类型和值存储在您需要的任何结构中并返回它。希望有帮助。
using System;
using System.Collections;
using System.Reflection;
class Animal
{
public string AnimalName { get; set; }
public string AnimalType { get; set; }
public int AnimalAgeInMonths { get; set; }
public int[] array { get; set; }
}
class Program
{
static void Main()
{
Animal animal = new Animal();
animal.AnimalName = null; // No name yet
animal.AnimalType = "Sheep";
animal.AnimalAgeInMonths = 7;
animal.array = new int[] { 1, 3, 5, 7, 9 };
class_info( animal );
}
static void class_info(object Class)
{
String val;
foreach (PropertyInfo propertyInfo in Class.GetType().GetProperties())
{
// Property Name ...
Console.WriteLine( propertyInfo.Name );
// Property type (as string) ...
Console.WriteLine( propertyInfo.PropertyType.ToString() );
// Property value (as string) ...
if ( propertyInfo.GetValue(Class, null) is null )
{
val = "null";
Console.WriteLine( val );
}
else
{
// Property is an array, show values (as strings) ...
if (propertyInfo.PropertyType.IsArray)
{
IEnumerable array = propertyInfo.GetValue( Class, null ) as IEnumerable;
if ( array is null )
{
Console.WriteLine( "Array is null" );
}
else
{
Console.WriteLine("Array values");
Console.WriteLine("------------");
foreach (var element in array)
Console.WriteLine(element.ToString());
}
}
else
{
val = propertyInfo.GetValue(Class, null).ToString();
Console.WriteLine( val );
}
}
}
}
}
看起来你只想要 3 个数组。其中每一个都可以通过 Reflection API 轻松获得。
static (string[], string?[], string[]) GetClassPropertyInfo(object o) {
// pass binding flags here if you want a different set of properties than default behaviour
var properties = o.GetType().GetProperties();
return (
properties.Select(x => x.Name).ToArray(),
properties.Select(x => x.GetValue(o)?.ToString()).ToArray(),
properties.Select(x => x.PropertyType.Name).ToArray()
);
}
关于第二个数组 - 您需要一种方法将任何属性值(包括
null
)转换为 string
。这里我刚刚调用了ToString
,如果值为null
,结果也是null。这就是为什么第二个数组具有可为 null 的元素,并且类型为 string?[]
。
关于第三个数组,
Name
返回简单名称,不带名称空间。如果您需要这样做,您可能需要改为 x.PropertyType.FullName ?? x.PropertyType.Name
,或者只是 x.PropertyType.ToString()
。
另请注意,您完全可以在 tuple 中返回 3 个内容,就像我在这里所做的那样,而不用将它们放入列表中。
也就是说,我建议为此创建一个 record 类型:
record ObjectInfo(string[] Name, string?[] Values, string[] Types);
你可以写:
return new ObjectInfo(
...
);
还要考虑也许它们不应该都是字符串。我认为这更有意义:
record ObjectInfo(string[] Name, object?[] Values, Type[] Types);