Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
the set and get methods allow for bounds check topermit a soft failure unlike the crash. Now my question is, if you have more than 2 different array which means you will need 2 different get/set methods.How are you going to have 2 get/set? How to accomodate teh bounds checking for b[].


C#
using System;

class arr
{
    public int[] a;
    public int[] b;
    public int len;
    public bool errflag;
    public arr(int sz) { len = sz; a = new int[len]; b = new int[len]; }
    public void display()
    {
        foreach(int x in a)
        {
            Console.WriteLine(x + " ");
            Console.Writeln();
        }
        foreach (int x in b)
        {
            Console.Write(x + " ");
            Console.Writeln();

        }
    }
    private bool ok(int index)
    {
        if (index >= len || index < 0)
            return false;
        return true;
    }
    public int this[int index]
    {
        get
            {
                if (ok(index))
                {
                    errflag = false;
                    return a[index];
                }
                else
                {
                    errflag = true;
                    return 0;
                }
            }
        set
            {
                if (ok(index))
                {
                    a[index] = value;
                    errflag = false;
                }
                else
                {
                    errflag = true;
                }
            }
    }
}
class arrdemo
{
    public static void Main()
    {
        arr obj = new arr(5);
        for (int i = 0; i < 6; i++)
        {
            obj[i] = 10 * i;//this refers to a[]
            obj.b[i] = 2 * i;//how would you accomodate b[]
        }
        obj.display();
    }
}
Posted
Comments
Firo Atrum Ventus 4-Aug-11 22:18pm    
What's wrong?
your code should run just fine.
Sergey Alexandrovich Kryukov 5-Aug-11 0:05am    
I finally figured out: this is a known problem of having more than one indexed property "this" in the same class. Interesting question. I provided a solution, please see.
--SA
Sergey Alexandrovich Kryukov 4-Aug-11 23:36pm    
What is "a soft failure unlike the crash"? I believe there is no such thing. What do you mean by that?
--SA
jackel7777 5-Aug-11 4:43am    
i come from a C++ background and this is my third day of C# programming. I have been exposed to defensive techniques but nevertheless system exceptions will terminate the program and this is not something you want...so thats why teh soft failure.....

SA is correct: you are bringing over C habits here which aren't really appropriate in the .Net world. If you find yourself typing something like
errflag = true;

... in C#, you probably need to stop and think about what you are doing. Exceptions are provided in the framework for exactly this type of thing, so your code can just go ahead and do its thing, and if someone passes a bad argument, they get an exception. If your higher level code is passing in user input, then it should probably use a try/catch to make sure that if the user enters rubbish there is a sensible notification. But the business level components should not be overly defensive.

.Net arrays are bounds checked for you, you don't have to worry about buffer overflows or anything. If you try to write off the end, you will get an exception, and that's exactly what you want.

Also, have you checked out the collections available in the language, particularly List<T>? You do not often need to use a naked array.

(Side note: my socket library is a slight violation of this, as various socket related exceptions do cause a normal appearing closure of the underlying socket. I/O is a bit different and an I/O library can legitimately handle certain exceptions. In general though it is not a responsibility of low level components.)

Regarding the actual question you asked, you can have two 'pseudo-arrays' with indexers by providing a wrapper class:

class ArrayWrapper<T> {
 private T[] array;
 
 public T this[int i]{
  get { return array[i]; }
  set {
   // any validation code here
   array[i] = value;
  }
 }
 
 public int Length { get { return array.Length; } } 

 public ArrayWrapper(int length) { array = new T[length]; }
}


... and then providing properties of that type in your class:

class arr {
 ArrayWrapper<int> a, b;

 ...
}</int>


But note that you should still not do validation in the getter ... if an invalid index is specified, allow that exception to be passed up to the code that made the mistake.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 5-Aug-11 15:03pm    
Thank you for adding arguments to my point! I agree with them. My 5.
--SA
First, answering the question about two "different get set". Your problem is not "get/set", but "this". Yes, you can make more that one "this", and the idea is pretty cunning. I'll explain how to do this, but it may not help you. How do you think the user code can tell one "this" from another "this"? Only be different index (or by different number of indices). Is you are interested to have two arrays in the same class (by some weird reason; I don't think you really need it), the index types would be different.

You know what? I'll assume you have two underlying arrays: one of rank 1, another of rank 2. This will resolve the issue and demonstrate the technique.

Now, I'll explain the idea. Read my leaps: declare two different indexed properties in two different interfaces and make your class implementing both interfaces. In fact, it's enough to have one interface.

C#
internal interface ITwoDimensionalArray {
    int this[int x, int t] { get; set; }
} //ITwoDimensionalArray

//...

internal class DoubleArray : ITwoDimensionalArray {
    internal DoubleArray(int arraySize, int array2SizeX, int array2sizeY) {
        array = new int[arraySize];
        array2 = new int[array2SizeX, array2sizeY];
    } //DoubleArray
    int[] array;
    int[,] array2;
    //...
    public int this[int x, int y] {
        get { return array2[x, y]; }
        set { array2[x, y] = value; }
    } //this 2-dimensional
    public int this[int index] {
        get { return array[index]; }
        set { array[index] = value; }
    } //this sinlge-dimentional
} //class DoubleArray


Problem solved!

Now (sight…), about your "soft failure". Bad idea! I'll now tell you what you should do, and you please don't get angry but think on what I suggests:

What the exceptions are for? Do not abuse them. Do the following: never check up any array index ranges or something like that. You don't need you "defensive" style of programming, you need "offensive" style. Let the user to make a mistake in range and let exceptions go! Of course, provide read-only access to the current array dimensions, but no more. What you do will only lead to a change of silent mistake. Who needs it. Exception would propagate somewhere on top of stack and will give the user a chance to fix the problem, if this is a bug. If there are no bug but there is an exception handled on top of UI cycle, the user will see some operation has failed. This is much better then the silent "soft" error.

So many inexperience developers abuse of misuse exceptions. Please read some of my past directions, it might help:
How do i make a loop that will stop when a scrollbar reaches the bottom[^],
When i run an application an exception is caught how to handle this?[^],
throw . .then ... rethrowing[^].

—SA
 
Share this answer
 
v3
Comments
BobJanova 5-Aug-11 10:45am    
5 for good advice about exceptions.
Sergey Alexandrovich Kryukov 5-Aug-11 15:02pm    
Thank you, Bob. For a record, OP's question is also answered.
--SA
Having two distinct arrays makes it impossible to access values from either array without specifying which array, unless you process the values in pairs.

So you could design get/set members that receive/return a struct or an array of two int values.

Another option is to augment the current get/set with a selection argument telling if you address a or b. In the case at hand, this could be a boolean argument.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900