I am currently trying to implement an "indexed" property within my class definition.
For example I have the following class:
public class TestClass
{
private int[] ids = null;
public string Name { get; set; }
public string Description { get; set; }
public int[] Ids {
get
{
//Do some magic and return an array of ints
//(count = 5 - in this example in real its not fixed)
return _ids;
}
}
}
Now I like to use this class as the following:
private void DoSomething()
{
var testClass = GetSomeTestClass();
//work with the ids
for (int i = 0; i < 10; i++) //I know I could say i < Ids.Length, its just an example
{
int? id = testClass.Ids[i];
//this will result, in a out of bound exception when i reaches 5 but I wish for it to return a null like a "safe" index call ?!?
}
}
So is there a safe index call that results in a null, without the need for me to wrap it again and again in a try catch.
Another thing I dont wish to use the class index, because I need several properties that work like this, with different types (int, string, bool, custom class and so on).
(Again the for is just a simple example, I know I could in this case say "i < Ids.Length")
To avoid the ArrayIndexOutOfBoundsException , the following should be kept in mind: The bounds of an array should be checked before accessing its elements. An array in Java starts at index 0 and ends at index length - 1 , so accessing elements that fall outside this range will throw an ArrayIndexOutOfBoundsException .
Index was outside the bounds of the array. That error message usually means that you have called for an object in the array at a location that is null, or has nothing there.
Another way of checking if an array is out of bounds is to make a function. This will check if the index is "in bounds". If the index is below zero or over the array length you will get the result false. This should be built in as a member function of the array class..
If you were only interested in already non-nullable type data e.g. struct
you could have gotten away with a simple extension method e.g.
public static class ArrayExt
{
public static Nullable<T> GetValueOrNull(this T[] array, int index) where T: struct
{
return array.Length < index ? new Nullable<T>(array[index]) : null;
}
}
which would have allowed you to simply call
int? id = testClass.Ids.GetValueOrNull(i);
However, given you need to support an arbitrary number of types my suggestion would be to implement a wrapper around an array and take control over how you access the data e.g.
public class SafeArray<T>
{
private T[] items;
public SafeArray(int capacity)
{
items = new T[capacity];
}
public object this[int index]
{
get
{
return index < items.Length ? (object)items[index] : null;
}
set
{
items[index] = (T)value;
}
}
}
public class TestClass
{
public TestClass()
{
Ids = new SafeArray<int>(5);
Instances = new SafeArray<MyClass>(5);
}
...
public SafeArray<int> Ids { get; private set; }
public SafeArray<MyClass> Instances { get; private set; }
}
The key to this approach is to use object
as the return type. This allows you to cast (or box/unbox if using value types) the data to the expected type on the receiving end e.g.
for (int i = 0; i < 10; i++)
{
// we need an explicit cast to un-box value types
var id = (int?)testClass.Ids[i];
// any class is already of type object so we don't need a cast
// however, if we want to cast to original type we can use explicit variable declarations e.g.
MyClass instance = testClass.Instances[i];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With