gpt4 book ai didi

c# - 是否可以按名称访问属性,这是一个变量?

转载 作者:太空宇宙 更新时间:2023-11-03 18:53:39 25 4
gpt4 key购买 nike

很抱歉,如果有人问和回答这个问题,我进行了搜索,但认为我不知道找到答案的词汇。研究过反射(reflection),但这似乎不是这里的答案?很明显我是新手。我正在为新的 Battletech 游戏尝试/做出一些小贡献。

我有这个 Dictionary 并想使用它的键来设置属性,如下面的 foreach 所示。我不知道这是在编译时还是在运行时,我猜是编译时...

我将 *limb* 作为伪代码放入其中,以说明我想象它可能如何工作。属性 mechDef.Head 是类型为 LocationLoadoutDef 的对象,其属性 CurrentInternalStructurefloat

希望这是有道理的!

非常感谢任何帮助。

public class Settings {
public readonly Dictionary<string, bool> LimbRepair = new Dictionary<string, bool> {
{ "Head", false },
{ "LeftArm", false },
{ "RightArm", false },
{ "CenterTorso", false },
{ "LeftTorso", false },
{ "RightTorso", false },
{ "LeftLeg", false },
{ "RightLeg", false },
};
}

MechDef mechDef = new MechDef
(__instance.DataManager.MechDefs.Get(id), __instance.GenerateSimGameUID());

foreach (string limb in settings.LimbRepair.Keys) {
if (!settings.LimbRepair[limb]) {
mechDef.*limb*.CurrentInternalStructure = Math.Max
(1f, mechDef.*limb*.CurrentInternalStructure * (float)rng.NextDouble());
}

最佳答案

你可以用反射来做,但是......

使用 Reflection 很容易做到这一点,你可能会在这里得到一些答案,告诉你如何做,但由于你正在编写游戏,我猜你想要尽可能最好的性能,而 Reflection 是总是会给你那个。

下面是一个不需要反射但仍然允许您使用所需循环结构的解决方案。它只需要在创建对象时进行一些设置,然后您就可以像在字典中一样访问您的属性。

解决方案:使用委托(delegate)字典来映射属性

首先,我们需要编写一个表示属性的实用程序类。由于属性可以是不同的类型,因此这是一个带有类型参数的泛型类。

class PropertyWrapper<T>
{
private readonly Func<T> _getter;
private readonly Action<T> _setter;

public PropertyWrapper(Func<T> getter, Action<T> setter)
{
_getter = getter;
_setter = setter;
}

public T Value
{
get
{
return _getter();
}
set
{
_setter(value);
}
}
}

这个类背后的想法是,您创建它来表示您想要的任何属性,并调用它的方法来读取和设置该属性。该类知道如何读取和设置该属性,因为您在构造它时通过向它传递一个完成工作的短 lambda 表达式来告诉它如何读取和设置该属性。

此实用程序将允许您将表示肢体的所有属性放入字典中。然后你可以通过字符串查找它们,就像你的设置一样。因此,例如您的 MechDefinition 可能如下所示:

class MechDef
{
public Limb Head { get; set; }
public Limb LeftArm { get; set; }
public Limb RightArm { get; set; }
public Limb LeftTorso { get; set; }
public Limb RightTorso { get; set; }
public Limb CenterTorso { get; set; }
public Limb RightLeg { get; set; }
public Limb LeftLeg { get; set; }

private readonly Dictionary<string, PropertyWrapper<Limb>> Properties;

public MechDef()
{
Properties = new Dictionary<string, PropertyWrapper<Limb>>
{
{"Head", new PropertyWrapper<Limb>( () => Head, v => Head = v ) },
{"LeftArm", new PropertyWrapper<Limb>( () => LeftArm, v => LeftArm = v ) },
{"RightArm", new PropertyWrapper<Limb>( () => RightArm, v => RightArm = v ) },
{"CenterTorso",new PropertyWrapper<Limb>( () => CenterTorso, v => CenterTorso = v )},
{"RightTorso", new PropertyWrapper<Limb>( () => RightTorso, v => RightTorso = v ) },
{"LeftTorso", new PropertyWrapper<Limb>( () => LeftTorso, v => LeftTorso = v ) },
{"RightLeg", new PropertyWrapper<Limb>( () => RightLeg, v => RightLeg = v ) },
{"LeftLeg", new PropertyWrapper<Limb>( () => LeftLeg, v => LeftLeg = v ) }
};

foreach (var property in Properties.Values) property.Value = new Limb();
}

public Limb this[string name]
{
get
{
return Properties[name].Value;
}
set
{
Properties[name].Value = value;
}
}
}

是的,那里有一些设置,但都在一个地方,并且只在您实例化 MechDef 时执行一次。现在您可以通过字符串访问所有肢体:

foreach (var pair in settings.LimbRepair)
{
if (pair.Value != false) continue;
var limb = mechDef[pair.Key];
limb.CurrentInternalStructure = Math.Max
(
1.0F,
limb.CurrentInternalStructure * (float)rng.NextDouble()
);
}

Link to DotNetFiddle example

关于c# - 是否可以按名称访问属性,这是一个变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50652187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com