调用列表中对象的方法或属性
本文关键字:方法 属性 对象 列表 调用 | 更新日期: 2023-09-27 18:37:07
我正在XNA游戏中编程一个调试窗口。这只是一个打印东西的StringBuilder
。但是,我想让它更具交互性。例如Player
类:
public class Player
{
public Vector2 Position { get; set; }
public int Health { get; set; }
}
我想有一个要调用的属性(或方法)列表。所以像这样:
list.Add(player1.Position);
list.Add(player1.Health);
list.Add(enemy2.Position);
因此,每次更新时,列表都会调用这些属性并打印其值。有什么办法可以做到这一点吗?我需要使用反射吗?使用方法而不是属性会有很大的不同吗?
编辑:这是我目前拥有的 https://github.com/nanexcool/xna-debug-window/blob/master/DebugWindow.cs
它通过将对象和属性名称指定为字符串来工作,但可能有更好的方法可以做到这一点。
使用属性名称和返回该属性的委托创建元组(或字典)列表:
using DebugTuple = Tuple<string, Func<string>>;
class Program
{
class Player
{
public int x;
public Player(int y) { x = y; }
}
static void Main(string[] args)
{
Player one = new Player(25);
Player two = new Player(50);
List<DebugTuple> calls = new List<DebugTuple>();
calls.Add(new DebugTuple("Player 1 health", delegate() { return one.x.ToString(); }));
calls.Add(new DebugTuple("Player 2 health", delegate() { return two.x.ToString(); }));
foreach (DebugTuple c in calls)
Console.WriteLine(c.Item1 + ": " + c.Item2());
//Change values and make sure it outputs new values
one.x = 100;
two.x = 0;
foreach (DebugTuple c in calls)
Console.WriteLine(c.Item1 + ": " + c.Item2());
Console.ReadLine();
}
}
输出:
Player 1 health: 25
Player 2 health: 50
Player 1 health: 100
Player 2 health: 0
也许有人也会发现这很有用:
/// <summary>
/// Represents your player class.
/// </summary>
class Player
{
/// <summary>
/// Gets or sets the health of the player.
/// </summary>
[DebugExtensions.DebugMePlease()]
public int Health { get; set; }
/// <summary>
/// Gets or sets the name of the player.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets a string representation of the player object.
/// </summary>
/// <returns>The player object as string representation.</returns>
public override string ToString()
{
return this.Name;
}
}
/// <summary>
/// Contains some extensions useful for debugging.
/// </summary>
public static class DebugExtensions
{
/// <summary>
/// Represents our custom attribute called "DebugMePlease".
/// Properties marked with this attribute will be printed automatically.
/// </summary>
public class DebugMePlease : Attribute
{
}
/// <summary>
/// Continas all objects that shall be monitored.
/// </summary>
public static List<object> DebugList
{
get;
set;
}
/// <summary>
/// Initializes static members of the <see cref="DebugExtensions"/> class.
/// </summary>
static DebugExtensions()
{
DebugList = new List<object>();
}
/// <summary>
/// Prints the values of all objects in the debugList.
/// </summary>
public static void Print()
{
foreach (object o in DebugList)
{
var members = from member in o.GetType().GetProperties()
from attribute in member.GetCustomAttributes(typeof(DebugMePlease), true)
select member;
foreach (var z in members)
{
Console.WriteLine(string.Format("{0}, {1}: {2}", o.ToString(), z.Name, z.GetValue(o)));
}
}
}
}
/// <summary>
/// Contains the entry point of our application.
/// </summary>
public class Program
{
/// <summary>
/// The entry point of our application.
/// </summary>
/// <param name="args">Possibly specified command line arguments.</param>
public static void Main(string[] args)
{
Player t = new Player();
t.Name = "Chuck Norris";
t.Health = int.MaxValue; // Becaus it's Chuck Norris ;-)
// Add the object to the debug list.
DebugExtensions.DebugList.Add(t);
// Print all properties marked with the "DebugMePlease" attribute.
DebugExtensions.Print();
// Change something.
t.Health = 0;
// Print again and hopefully be happy.
DebugExtensions.Print();
Console.ReadLine();
}
}
也许我误解了一些东西,但是如果您已经有一个包含引用的列表,那么您不能使用 .ToString()?(当然,您必须在自己的类中覆盖 ToString()。