HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Color structure with single field for multiple properties

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
fieldwithpropertiescolorsinglestructureformultiple

Problem

This struct is used a lot throughout my programme. This struct is responsible for only things regarding colour, not anything else.

I'm largely concerned of the bitwise operations, and the fact that I store four byte values in a uint but access them with bitwise flags. This is a concept I use throughout the programme. (I have one struct that has a 14-bit field, and two 7-bit fields.)

```
///
/// A structure to represent a generic set of Red, Green, Blue and Alpha to represent the shade to paint an object.
///
public struct Color
{
private uint _PackedValue;

///
/// Gets or sets the Alpha component of the .
///
public byte A { get { return (byte)((_PackedValue & 0xFF000000u) >> 0x18); } set { _PackedValue = (_PackedValue & ~0xFF000000u) | ((uint)value
/// Gets or sets the Red component of the .
///
public byte R { get { return (byte)((_PackedValue & 0x00FF0000u) >> 0x10); } set { _PackedValue = (_PackedValue & ~0x00FF0000u) | ((uint)value
/// Gets or sets the Green component of the .
///
public byte G { get { return (byte)((_PackedValue & 0x0000FF00u) >> 0x08); } set { _PackedValue = (_PackedValue & ~0x0000FF00u) | ((uint)value
/// Gets or sets the Blue component of the .
///
public byte B { get { return (byte)((_PackedValue & 0x000000FFu) >> 0x00); } set { _PackedValue = (_PackedValue & ~0x000000FFu) | ((uint)value
/// Creates an instance of a .
///
/// The alpha byte component.
/// The red byte component.
/// The green byte component.
/// The blue byte component.
public Color(byte r, byte g, byte b, byte a)
{
_PackedValue = ((uint)a
/// Creates an instance of a with a default alpha of 255.
///
/// The red byte component.
/// The green byte component.
/// The blue byte component.
public Color(byte r, byte g, byte b)
{
_PackedValue = ((uint)0xFF
/// Creates an instance of a from a packed value.
///
/

Solution

An alternative is to create a union, a structure with overlapping values, by adding the StructLayout and FieldOffset attributes. This elegantly allows you to overlay the uint on top of the byte members.

using System.Runtime.InteropServices;




[StructLayout(LayoutKind.Explicit)]
public struct Color
{

    [FieldOffset(0)] private uint value;
    [FieldOffset(0)] private byte b;
    [FieldOffset(1)] private byte g;
    [FieldOffset(2)] private byte r;
    [FieldOffset(3)] private byte a;

    public Color(uint value) : this(0, 0, 0, 0)
    {
        this.value = value;
    }

    public Color(byte r, byte g, byte b) : this(r, g, b, 255)
    {
    }

    public Color(byte r, byte g, byte b, byte a)
    {
        this.value = 0;
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }

    public uint Value
    {
        get
        {
            return this.value;
        }
        set
        {
            this.value = value;
        }
    }

    public byte R
    {
        get
        {
            return this.r;
        }
        set
        {
            this.r = value;
        }
    }

    public byte G
    {
        get
        {
            return this.g;
        }
        set
        {
            this.g = value;
        }
    }

    public byte B
    {
        get
        {
            return this.b;
        }
        set
        {
            this.b = value;
        }
    }

    public byte A
    {
        get
        {
            return this.a;
        }
        set
        {
            this.a = value;
        }
    }

}

Code Snippets

using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
public struct Color
{

    [FieldOffset(0)] private uint value;
    [FieldOffset(0)] private byte b;
    [FieldOffset(1)] private byte g;
    [FieldOffset(2)] private byte r;
    [FieldOffset(3)] private byte a;

    public Color(uint value) : this(0, 0, 0, 0)
    {
        this.value = value;
    }

    public Color(byte r, byte g, byte b) : this(r, g, b, 255)
    {
    }

    public Color(byte r, byte g, byte b, byte a)
    {
        this.value = 0;
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }

    public uint Value
    {
        get
        {
            return this.value;
        }
        set
        {
            this.value = value;
        }
    }

    public byte R
    {
        get
        {
            return this.r;
        }
        set
        {
            this.r = value;
        }
    }

    public byte G
    {
        get
        {
            return this.g;
        }
        set
        {
            this.g = value;
        }
    }

    public byte B
    {
        get
        {
            return this.b;
        }
        set
        {
            this.b = value;
        }
    }

    public byte A
    {
        get
        {
            return this.a;
        }
        set
        {
            this.a = value;
        }
    }

}

Context

StackExchange Code Review Q#98605, answer score: 10

Revisions (0)

No revisions yet.