我在c#中只有一个参数,只有一个参数(它是一个覆盖所以我不能改变它的签名以包含更多参数):
read_address(long adr)
其中adr是我想要读取的地址存储器,但我必须传递地址并同时指示要读取的地址是16位还是32位,如果是32位,此外我必须指出是否需要读取大写或小写单词,以便我想知道使用参数adr执行此操作的有效方法。
我想构建一个掩码,例如,如果我想读取地址614(十进制),我可以在之前或之后添加两个数字:
10614:第一个数字1表示大小= 32位,第二个数字0表示低位词
11614:第一个数字1表示大小= 32位,第二个数字1表示大写字母
表示16位,无需指示低位或高位:
00614 = 614将指示16位。
我也可以通过将这两位数字放回去来完成:
61410
61411
因此,当我通过addr参数接收到这个数字时,我必须解析它以确定它是16位还是32位,如果是32位则是低位或高位字。
编辑:
我想我没有好好解释......
例如,可以看出这个方法,read_address,receive和address(addr)要读取。这是从另一个方法method_A调用的,它知道这是16位还是32位,如果是32位,它会分成两个字。更好的例子,对于阅读614:
Method_A(....)
{
if 16-bit then
{
call read_address(620) // Supose 620 is 16 bit
}
if 32-bit then
{
// suppose 614 is 32 bit so split into two reads
call read_address(61410) // to read first word
call read_address(61411) // to read second word
}
}
所以在read_address中我必须知道它是16位还是32位,如果是32位,我还必须知道它是低位还是高位字。
read_address(long addr)
{
// decode if addr is 16 or 32 bit and if 32 bit, decode if lower
// or upper word and do some stuff
// So suppose it arrives 61410... how to decode it in order to know,
// address to read is 614 and is 32-bit (1) and I want to read lower word (0)
}
答案 0 :(得分:3)
你提到“上/下”字只在addr指定一个32位地址时计数 - 我希望你的意思是它只计算16位? (如果不是,你怎么知道值“10”是掩码还是地址?)
我不会对掩码使用小数位,而是将64位分成两个32位数(整数),并使用二进制标记。
然后将示例614作为二进制的64位数字(我希望我得到了字节顺序,但它应该说明情况):
00000010 00000000 00000000 00000000 01100110 00000010 00000000 00000000
| Mask | | Address |
然后,您可以使用[Flags] enum
来定义掩码,并将掩码整数强制转换为该枚举。以下是创建和解析地址的示例:
public void Main()
{
// Some test values.
ushort address16 = ushort.MaxValue;
uint address32 = uint.MaxValue;
// Upper:
ulong valueUpper = address16; // Value contains 0x000000000000FFFF
valueUpper = valueUpper << 48; // Value contains 0xFFFF000000000000
valueUpper += (uint)Mask.Upper; // Value contains 0xFFFF000000000001
// Lower:
ulong valueLower = address16; // Value contains 0x000000000000FFFF
valueLower = valueLower << 32; // Value contains 0x0000FFFF00000000
// No need to set a 0-bit, it is already 0
// DWord:
ulong valueDword = address32; // Value contains 0x00000000FFFFFFFF
valueDword = valueDword << 32; // Value contains 0xFFFFFFFF00000000
valueDword += (uint)Mask.DoubleWord; // Value contains 0xFFFFFFFF00000010
ulong addr1 = ParseAddress((long)valueUpper);
ulong addr2 = ParseAddress((long)valueLower);
ulong addr3 = ParseAddress((long)valueDword);
}
public ulong ParseAddress(long address)
{
// Casting to ulong, as negative values don't make sense in addresses or bitwise operations.
ulong value = (ulong)address;
// Take the mask from the least significant bits
Mask mask = (Mask)(value & uint.MaxValue);
// Shift the mask bytes "off" the addr, get the remaining address.
ulong addr = ((ulong)value >> 32);
// Is the doubleword bit set?
if ((mask & Mask.DoubleWord) == Mask.DoubleWord)
{
return addr;
}
else if ((mask & Mask.Upper) == Mask.Upper)
{
return (addr >> 16);
}
else
{
return addr;
}
}
[Flags]
public enum Mask : uint
{
Upper = 1,
DoubleWord = 2,
}
答案 1 :(得分:0)
它是一个覆盖,因此我无法更改其签名以包含更多内容 参数
虽然您无法覆盖虚拟方法并同时更改其签名,但可以在您的子类中定义一个带有这些额外参数的重载。 e.g:
class SuperClass
{
public virtual void read_address(long adr)
{
}
}
class SubClass : SuperClass
{
public override void read_address(long adr)
{
// call the overload with your default values e.g. 32 and false
this.read_address(adr, 32, false);
}
public void read_address(long adr, int bytesToRead, bool upper)
{
// ...
}
}