(很抱歉,如果重复的话,但是我已经做了很多搜索,还没有找到答案)
我目前正在使用对象保存/加载系统,该系统允许我在会话之间保存数据,即设置等。我当前的“保护程序”要求我输入一个字符串作为设置的名称,这不太费力。但是,我开始扩展系统,并且我将保存数十个(即使不是数百个)对象(虽然不经常使用)。现在,必须将名称作为参数传递非常困难,因为我正在使用for
循环,因此除非我想为名称创建一个新列表,否则我需要更好的方法。
编辑(添加了我想要的示例):
void LogName(object obj)
{
Debug.Log(GetNameOfParam(obj));
DoStuff();
}
LogName(ObjectToSave);
这应该记录“ ObjectToSave”而不是“ obj”
我尝试了许多不同的解决方案:
obj.GetType().Name
,它只输出类型名称
nameof(obj)
,输出“ obj”
甚至
public static string GetName<T>(Expression<Func<T>> expr)
{
MemberExpression body = ((MemberExpression)expr.Body);
string name = body.Member.Name;
//object value = ((FieldInfo)body.Member).GetValue(((ConstantExpression)body.Expression).Value);
return name;
}
GetName(() => obj)
这也给了我“ obj”。
编辑(添加的代码): 覆盖代码:
private void OverwriteObject(object obj)
{
string name = obj.GetType().Name;
Debug.Log($"GetType.Name:{obj.GetType().Name}");
Debug.Log($"nameof:{nameof(obj)}");
Debug.Log($"GetName<T>:{ObjectExtensions.GetName(() => obj)}");
string path = Paths.SettingsSaveLocation + Paths.SettingFilePrefix + name + Paths.SettingFileSuffix;
//If setting file exist, read it
if (File.Exists(path))
{
try
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
//Create buffer and read data
byte[] data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
//Load data into setting object
JsonUtility.FromJsonOverwrite(Encoding.UTF8.GetString(data), obj);
}
}
catch (Exception e)
{
Debug.LogException(e);
}
}
//Otherwise, create a new one
else
{
WriteObj(name, obj);
}
}
写代码:
private void WriteObject(string name, object obj)
{
string path = Paths.SettingsSaveLocation + Paths.SettingFilePrefix + name + Paths.SettingFileSuffix;
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
//Use prettyPrint so it looks nicer
string data = JsonUtility.ToJson(obj, true);
fs.Write(Encoding.UTF8.GetBytes(data), 0, data.Length);/**/
}
}
For循环(不完整,需要工作):
foreach (var obj in GameObject.FindGameObjectsWithTag("Enemy"))
{
WriteObject("Object name is xyzasd123", obj);
}
答案 0 :(得分:0)
如果不是您要查找的类型名称,并且该名称反映了方法的反射参数名称,则需要将该名称存储在每个对象的公共属性中。
例如,创建一个名为IObjectName
的接口。
public interface IObjectname
{
string ObjectName { get; set; }
}
每个应有名称的对象都应实现此接口。
现在,您可以将方法更改为以下形式:
void LogName(IObjectName obj)
{
Debug.Log(obj.Name);
DoStuff();
}
或者您可以强制转换参数IObjectName
,但是如果类型不实现接口,则会抛出InvalidCastException
。
例如:
void LogName(object obj)
{
// Risk that InvalidCastException will be thrown.
Debug.Log((obj as IObjectName).Name);
DoStuff();
}
希望这可以解决您的问题。