Warm tip: This article is reproduced from serverfault.com, please click

c#-使用带有版本开关的Get / Set定义属性的最有效方法是什么?

(c# - What is the most efficient way to define a property using Get/Set with a switch for versions?)

发布于 2020-11-30 14:45:23

我正在编写一个程序以从另一个程序读取和写入内存,但是有两个不同的版本,并且一个版本的内存值具有偏移量,而第二个版本中的内存值没有偏移量,因此取决于用户选择的设置(v1或v2 )我需要确定要读取/写入的地址。

目前,我的代码如下,但是我不觉得这非常有效,并且复制相同的代码会使该类在不需要时变得很长。

有没有更有效的方式来完成所有这些工作:

public static int Property
{
    get
    {
        switch (Version)
        {
            case Version.v1:
                return Memory.ReadMemory<int>(0xB7CE50 + 0x2680);
            case Version.v2:
                return Memory.ReadMemory<int>(0xB7CE50);
            default:
                return 0;
        }
    }
    set
    {
        switch (Version)
        {
            case Version.v1:
                Memory.WriteMemory<int>(0xB7CE50 + 0x2680, value);
                break;
            case Version.v2:
                Memory.WriteMemory<int>(0xB7CE50, value);
                break;
            default:
                break;
        }
    }
}

并非所有地址都需要此偏移量,但大多数地址都需要此偏移量,因此我也需要考虑这个偏移量,因此如果v2我不能仅添加0x2680值

Questioner
RobertEves92
Viewed
0
canton7 2020-11-30 23:19:00

解决此问题的一种显而易见的方法是将生活在何处的知识带到中心位置。你可能想要扩展对a的定义Version以包括内存地址(请参见下文),或者你可能希望将此信息包含在其他一些类中:

public class Version
{
    public int PropertyAddress { get; init; }

    public static Version Version1 { get; } = new()
    {
        PropertyAddress = 0xB7CE50 + 0x2680,
    };

    public static Version Version2 { get; } = new()
    {
        PropertyAddress = 0xB7CE50,
    };

    private Version() { }
}

(我在这里使用了C#9语法-如果你要定位的是较早的语言版本,请进行调整)。

然后,你可以将属性简化为:

public static int Property
{
    get => Memory.ReadMemory<int>(Version.PropertyAddress);
    set => Memory.WriteMemory<int>(Version.PropertyAddress, value);
}

你也可以将其放在一个MemoryAddresses类中(如果你想保留Version为枚举),然后执行以下操作:

private static MemoryAddresses Addresses => Version switch
{
    Version.V1 => MemoryAddresses.V1,
    Version.V2 => MemoryAddresses.V2,
};

public static int Property
{
    get => Memory.ReadMemory<int>(Addresses.PropertyAddress);
    set => Memory.WriteMemory<int>(Addresses.PropertyAddress, value);
}

如果要利用一个版本中的某些地址是另一版本中的地址的偏移版本这一事实,可以执行以下操作:

public class Version
{
    public int Offset { get; init; }

    public int Property1Address => 0xB7CE50 + Offset;
    public int Property2Address => 0xB80000 + Offset;
    public int Property3Address { get; init; }

    public static Version Version1 { get; } = new()
    {
        Offset = 0x2680,            // <-- Offset for version 1
        Property3Address = 123456,  // <-- Explicit address for version 1
    };

    public static Version Version2 { get; } = new()
    {
        Offset = 0,                 // <-- No offset for version 2
        Property3Address = 987654,  // <-- Different explicit address for version 2
    };

    private Version() { }
}