在一行 C# 中为公共字节数组赋值

Posted

技术标签:

【中文标题】在一行 C# 中为公共字节数组赋值【英文标题】:Assigning values to a public byte array in one line C# 【发布时间】:2013-08-21 13:30:08 【问题描述】:

我正在使用一个公共字节数组并希望分配值,就像我在方法中分配数组一样,即

byte[] foo = 0x32, 0x00, 0x1E, 0x00;

但是当我定义值时,我不得不这样做

foo[0] = 0x32;
foo[1] = 0x00;
foo[2] = 0x1E;
foo[3] = 0x00;

如果我使用第一个例子VS给出错误“只有赋值、调用、递增、递减、等待和新对象表达式可以用作语句”

如果有帮助,数组总是 4 个字节。

我的代码

public byte[] SetSpeed = new byte[4];
private void trackBar1_Scroll(object sender, EventArgs e)

    if (trackBar1.Value == 0)
    
        try
        
            stop = true;
            UpdateSThread.Abort();
            Thread.Sleep(350);
        
        catch  
        SetSpeed = 0x00,0x00,0x00,0x00;
        WriteMem(GetPlayer() + STATUS_OFFSET, SetSpeed);
        label1.Text = "Normal";              
    

【问题讨论】:

请发布一个简短但完整的失败示例。我希望你给的东西没问题 - 但如果你只是分配给 foo 而不声明它。 你的第一个例子编译(VS2012) 您仍然没有显示无法编译的代码。我怀疑您正在尝试SetSpeed = 0x00, 0x00, 0x00, 0x00 ,这与您的原始示例完全不同。此外,您还没有明确说明您是真的想创建一个新数组还是只想改变现有数组。 我现在举的例子是不能编译的。 @user2340475:最后。这就是应该开始的问题。 【参考方案1】:

您的第一个示例很好,但它只能在声明中使用。元素必须隐式转换为元素类型。大小由给定的元素数量决定。

byte[] foo =  0x32, 0x00, 0x1E, 0x00 ;

或者你也可以这样做

byte[] foo = new byte[4];
foo[0] = 0x32;
foo[1] = 0x00;
foo[2] = 0x1E;
foo[3] = 0x00;

如上所述,您尝试使用的语法只能在声明中使用。所以试试这样。

public byte[] SetSpeed;
private void trackBar1_Scroll(object sender, EventArgs e)

    if (trackBar1.Value == 0)
    
        try
        
            stop = true;
            UpdateSThread.Abort();
            Thread.Sleep(350);
        
        catch  

        //note it will always create a new array
        SetSpeed = new byte[]0x00,0x00,0x00,0x00; 
        WriteMem(GetPlayer() + STATUS_OFFSET, SetSpeed);
        label1.Text = "Normal";              
    

【讨论】:

没有需要这样做 - 原始代码无论如何都会编译。 谢谢,这行得通,我想我模糊了,公共标签是相关的,但被删除了。不用担心,我得到了答案【参考方案2】:

当您声明一个变量时,您只能使用未指定new 的形式。所以这很好:

byte[] x =  1, 2, 3 ;

但这不是:

byte[] x;
x =  1, 2, 3 ;

相反,您需要类似:

byte[] x;
x = new byte[]  1, 2, 3 ;

或者对于类型推断对您有利并且您使用 C# 3 或更高版本的情况,您可以使用隐式类型数组:

string[] x;
x = new[]  "a", "b", "c" ;

但是,您确实需要决定是想要创建一个新数组,还是要改变现有数组。鉴于您只是将所有值设置为 0,您可以改用:

Array.Clear(SetSpeed, 0, 4);

编辑:现在问题包含以下内容:

我想更改现有数组中的值,

然后使用

SetSpeed = new byte[]  ... 

合适,因为这会将SetSpeed的值更改为引用一个不同的数组。

要更新现有数组,您可以只使用 4 个单独的语句,也可以将其提取到具有 4 个参数的单独方法中。目前还不清楚这些值将是什么,因此很难为您提供最好的代码。

【讨论】:

感谢您对 Array.Clear 的建议,轨迹栏上的下一个刻度,确实开始添加值 > 0。 @user2340475:但是您仍然需要决定是否需要一个新数组。还有其他东西已经引用了数组吗? 它是Array.Clear(SetSpeed, 0, 4);((IList<byte>)SetSpeed).Clear(); @JeppeStigNielsen:谢谢,已修复。 不,不是,当track bar移出0时,启动线程循环更新内存中的值,值为SetSpeed,当带回0时,线程退出,值在内存中设置回 0 的 4 个字节【参考方案3】:

给出的例子

byte[] foo = new byte[]  0x32, 0x00, 0x1E, 0x00 ;

不会为现有 byte[] 赋值:而是用对 byte[] 的引用替换引用。如果没有更多上下文,这种方法可能(或可能不起作用),例如公共byte[] 可能是只读的,即:

public byte[] Foo  get ; private set ; 

你可以做的是使用Array.Copy()的静态重载:

byte[] newBytes = GetSomeBytes() ;
Array.Copy( newBytes , Foo , Foo.Length ) ;

或者您可以编写一个扩展方法(如果您愿意,可以包装 Array.Copy):

public static CopyFrom<T>( this T[] target , int offset , params T[] source )

  foreach ( T value in values )
  
     // Throws IndexOutOfRangeException if offset exceeds destination length
     target[offset++] = value ; 
  

这会让你做这样的事情:

public byte[] Foo  get ; private set ; 
.
.
.
Foo.CopyFrom( 0, 1,2,3,4 ) ;
.
.
.
Foo.CopyFrom( 1, new byte[]1,2 ) ;

【讨论】:

以上是关于在一行 C# 中为公共字节数组赋值的主要内容,如果未能解决你的问题,请参考以下文章

java和c#的字节数组转换问题

字节数组赋值问题?

使用模数和公共指数的 C# RSA 加密

在 C# 中使用字节数组

C#如何从字节数组中提取字节?已知起始字节

将 C# 3D 数组作为 1D 字节数组传递给 C++ 库