• I removed the www from the URL, please update your bookmarks and pay attention to the bottom of the screen if using Google Chrome to allow push notifications again.

How to manipulate BitArrays

Samuel

New member
Joined
Apr 14, 2019
Messages
3
Programming Experience
Beginner
This is my first post here. I am trying to learn C#, and have no development experience. I found the code below and can not follow what is going on in the sections I have labeled.
BitArray implementation of Indexers:
class BitArray
{
    int[] bits;
    int length;

    public BitArray(int length) {
        if (length < 0) throw new ArgumentException();
        bits = new int[((length - 1) >> 5) + 1];
        this.length = length;
    }

    public int Length {
        get { return length; }
    }

    public bool this[int index] {
        get {
            if (index < 0 || index >= length) {
                throw new IndexOutOfRangeException();
            }//What is happening in the line below?
            return (bits[index >> 5] & 1 << index) != 0;
        }
        set {
            if (index < 0 || index >= length) {
                throw new IndexOutOfRangeException();
            }// Also in the if statement below I do not see what is going on
            if (value) {
                bits[index >> 5] |= 1 << index;
            }// Same here in the else block, what is happening?
            else {
                bits[index >> 5] &= ~(1 << index);
            }
        }
    }
}
I got the code from here.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,230
Location
Sydney, Australia
Programming Experience
10+
Why are you even looking at that code in the first place? What are you actually trying to achieve?
 

Samuel

New member
Joined
Apr 14, 2019
Messages
3
Programming Experience
Beginner
Why are you even looking at that code in the first place? What are you actually trying to achieve?
I am reading the C# via CLR book by Jeff Richer. On page 622 he has the following code:
C#:
[Serializable]
public class Dictionary<TKey, TValue>: ISerializable, IDeserializationCallback {
// Private fields go here (not shown)
private SerializationInfo m_siInfo; // Only used for deserialization
// Special constructor (required by ISerializable) to control deserialization
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
protected Dictionary(SerializationInfo info, StreamingContext context) {
// During deserialization, save the SerializationInfo for OnDeserialization
m_siInfo = info;
}
// Method to control serialization
[SecurityCritical]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
info.AddValue("Version", m_version);
info.AddValue("Comparer", m_comparer, typeof(IEqualityComparer<TKey>));
info.AddValue("HashSize", (m_ buckets == null) ? 0 : m_buckets.Length);
if (m_buckets != null) {
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[Count];
CopyTo(array, 0);
info.AddValue("KeyValuePairs", array, typeof(KeyValuePair<TKey, TValue>[]));
}
}
// Method called after all key/value objects have been deserialized
public virtual void IDeserializationCallback.OnDeserialization(Object sender) {
if (m_siInfo == null) return; // Never set, return
Int32 num = m_siInfo.GetInt32("Version");
Int32 num2 = m_siInfo.GetInt32("HashSize");
m_comparer = (IEqualityComparer<TKey>)
m_siInfo.GetValue("Comparer", typeof(IEqualityComparer<TKey>));
if (num2 != 0) {
m_buckets = new Int32[num2];
for (Int32 i = 0; i < m_buckets.Length; i++) m_buckets[i] = -1;
m_entries = new Entry<TKey, TValue>[num2];
m_freeList = -1;
KeyValuePair<TKey, TValue>[] pairArray = (KeyValuePair<TKey, TValue>[])
m_siInfo.GetValue("KeyValuePairs", typeof(KeyValuePair<TKey, TValue>[]));
if (pairArray == null)
ThrowHelper.ThrowSerializationException(
ExceptionResource.Serialization_MissingKeys);
for (Int32 j = 0; j < pairArray.Length; j++) {
if (pairArray[j].Key == null)
ThrowHelper.ThrowSerializationException(
ExceptionResource.Serialization_NullKey);
Insert(pairArray[j].Key, pairArray[j].Value, true);
}
} else { m_buckets = null; }
m_version = num;
m_siInfo = null;
}
While I get the point he tried to make, I can not follow what is going on every line. So I started looking up the parts I did not get. The first one was Dictionary<TKey, TValue>, and I could not follow how Indexers worked, so I looked up indexer specification which gave an example of indexers are used in BitArrays, and I think that is how I found the language reference. If I understand Indexers well, I think I would be all set. I just need an explanation that does not involve shift to left or right operations I guess. For instance the code below they use "this" keyword to refer to the indexer, and I have never seen "[]"s used for a member field before.
C#:
using System;

class SampleCollection<T>
{
   // Declare an array to store the data elements.
   private T[] arr = new T[100];

   // Define the indexer to allow client code to use [] notation.
   public T this[int i]
   {
      get { return arr[i]; }
      set { arr[i] = value; }
   }
}

class Program
{
   static void Main()
   {
      var stringCollection = new SampleCollection<string>();
      stringCollection[0] = "Hello, World";
      Console.WriteLine(stringCollection[0]);
   }
}
// The example displays the following output:
//       Hello, World.
I have to say reading through the language specification helped me with some gaps in what I knew about C# class. For instance, I did not understand properties well and how accessors worked, but I feel a lot better about it now. Why is that not a good read for someone like me? Would you elaborate please?
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,230
Location
Sydney, Australia
Programming Experience
10+
Why is that not a good read for someone like me?
I didn't say that it wasn't. You seem to be assuming that there was some nefarious intent in my question. There wasn't. It was a question intended to elicit information that could help me better answer your question. As it turns out, it was a good idea because it seems that the question you asked is not really the question you want answered. If you want to know about indexers then it's probably a good idea to ask about indexers.

Anyway, and indexer in a C# class is basically a special property that allows you to access data within the class by index. The brackets notation is how you specify an index in C#. If you have ever used arrays then you would be familiar with that, e.g.
C#:
// Create a new array with 12 elements.
var squares = new int[12] {};

// Set each element.
for (var i = 0; i < numbers.Length; i++)
{
    squares[i] = i * i;
}

// Display each element.
for (var i = 0; i < numbers.Length; i++)
{
    Console.WriteLine(squares[i]);
}
Just as you index an array using brackets, so you index a class with an indexer using brackets. The SampleCollection class in your last code snippet could be used in virtually the same way.

The indexer itself is pretty much like a regular property, with a getter and setter. It is always named this though, and it can have one or more parameters, just like a method. As you noticed though, those parameters are specified within brackets rather than parentheses though. More often than not, an index would be a sequential numeric value, as for an array. They could be something else though, e.g. an arbitrary string key or other object, as for a Dictionary. A Dictionary is something like an array in that it contains multiple values, but those values are identified by their relationship to unique key values rather than a sequential numerical order.
 

Samuel

New member
Joined
Apr 14, 2019
Messages
3
Programming Experience
Beginner
Thank you so much. You are right, I am defensive without realizing that I do that. Thanks for clarification, and thank you so much for taking the time to explain the topic. As you know some forums are a bit stringent on what people ask, and the format and whether they have researched the topic. This helped me realize I should be more patient and provide the requested details without assuming. Greatly appreciate your response.
 
Top Bottom