How to check if key pair in 2D array exists? - c#

I have this 2d array or struct
public struct MapCell
{
public string tile;
}
public MapCell[,] worldMap;
But there's no way to check if key pair is exists in this array or not... No methods for that available.
I tried to do it like this
if (worldMap[tileX, tileY] != null) {
}
it doesnt work:
Error 1 Operator '!=' cannot be applied to operands of type 'Warudo.MapCell' and '<null>'
and for
if (worldMap[tileX, tileY].tile != null) {
it doesn't work either (exception pops up when it hits non existing element).
Index was outside the bounds of the array.
So, how do I check if key pair is exists or not?

You never mentioned which error you are getting -- array out of bounds or a null reference. If you are getting array out of bounds you should precede your null check with something along the lines of...
// make sure we're not referencing cells out of bounds of the array
if (tileX < arr.GetLength(0) && tileY < arr.GetLength(1))
{
// logic
}
Of course, it's best to just store the maximum array bounds instead of getting their lengths each time.
I also second (third?) the recommendation for using a class and not a struct.
Edit: Are you ever actually initializing this field? You haven't included it in your code sample. For example worldMap = new MapCell[100,100];, and then fill up the array...

If you're using an array of struct values, they always exist (once the array is constructed), but have their default value until you set them.
I would recommend using a class here instead of a struct. This will allow you to check for null, as well as act more in an expected fashion if you're going to be changing values (which, given the names, I expect...)
That being said, you could check for whether the string within the struct is null:
if (worldMap[tileX, tileY].tile != null)
{
// You've set the "tile" field inside of this "cell"...
This works because the default value of a struct is initialized with all references, including strings, to null.

Related

Passing a C# array as a function parameter to allocate its memory does not work

Since passing a C# array as a function parameter is pass-by-reference, that means I can modify the array in the function. So here I am trying to allocate and modify the array in the function:
void caller() {
int array[];
doStuff(array);
if (array != null) {
// never reaches here, even when I allocated the array of size 0
}
}
void doStuff(int[] array) {
int[] tmp = new int[0];
array = new int[tmp.Length];
}
Problem is that the array != null check never turns out to be true, even when I have allocated an array of size 0. I've confirmed in documents that new int[0] is a valid allocation command. What could I be doing wrong?
That will never work, unless you pass by reference.
Your first variable is null, when you pass it along you pass along a reference (by value!) to nothing. Your method than assigns its copy of the reference to some other array. That won't affect the original variable.
If you want that to work, you have to actually pass by reference (using out or ref).
since the array is initialized (with the new int command), it will never be null, just an declared empty space (with no data). You can check the length in the caller method, in the if.

TargetParameterCountException when iteratively retrieving value out of reflexive properties of a string

Some context first :
I was writing a reusable "null tester" method that will be used to check if any variable of an object has a null or empty value. the goal is that the method can take an Object and use reflexion to check the value of each property.
Everything worked until I added a List<string> to a class that is being checked.
While adding List<string> raised the TargetParameterCountException other primitive types didn't. The only other time I managed to reproduce this error is when I passed directly a string.
I managed to boil down this problem to that bit of code :
string toCheck = "foo";
var elementProperties = toCheck.GetType().GetProperties();
foreach (PropertyInfo property in elementProperties)
{
var elementValue = property.GetValue(toCheck);
//Check if "toCheck" is null or empty here
}
elementProperties has two Values
An Int32 Length
A Char Chars[Int32]
My understanding would be that the first represent the length and the second the content of the string. But when the code tries to "GetValue()" the second property it raises a TargetParameterCountException.
Does someone know why it would do that ?
since I was trying to access a char array I needed to specify the index of which char I want to retrieve.
using :
property.GetValue(toCheck, new object[] {index})

Advantages of indexers over object array?

I read about indexers in MSDN - Indexers which explains how we can use objects like array with index i.e. just like normal Array. However, I think we can create array of objects like
point[] array = new point[100];
So what is the special advantages Indexer over object array?
If all you are after is a collection of objects then an indexer has absolutely no benefit over an array. However, if you need to store state as well as a collection, that's where an indexer shines.
For example, consider the following
public class Tree
{
private Branch[] branches = new Branch[100];
...
public string Name { get; set; }
public Branch this[int i]
{
get
{
return branches[i];
}
}
}
Tree holds an internal collection but also has state of it's own. Having an indexer property allows for simple access to the underlying collection e.g.
tree.Name = "Tree";
var branch = tree[0];
Not in this case that you have mentioned above. However, if you have anything that cannot be represented as an array will be a good example for Indexers to be used.
One .Net framework example is Dictionary. If you see the definition of Dictionary type in .Net you will find that they let you get an access of value through key. So that is a good example of using indexers where the index is presented as string.
Without indexers, how would you do that? of course by index value but it cannot be of type string then, will that be user friendly? I guess not!
So indexers gives you an opportunity to represent your code well.
Similarly, in case of point type, of course you can access the value of by index i.e. 0,1,2...99. What if you want to make more user friendly, such as point["x"]. That is where Indexers will help you.
Another example I could think of how about if you want to access your stack like s1 instead of push and s[0] instead of pop method.
There is a very good example of indexers by Microsoft where you can access file byte by byte by providing character location as index.
http://msdn.microsoft.com/en-us/library/aa288465(v=vs.71).aspx
In your line of code, you've defined an array of point objects, whatever those might be.
point[] array = new point[100];
Assuming you have direct access to the array, you can access the first element in your array like this:
var firstPoint = array[0];
The page you linked to is showing you how you could access that array, if it were defined inside your class, and you didn't have direct access to the array (since it's private).
For example, we could modify the example on that page to use your array:
class SampleCollection
{
private Point[] arr = new Point[100];
public Point this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
Then you could access the first element in the array like this:
var sc = new SampleCollection();
var item1 = sc[0];
That isn't an indexer.
An indexer is not used to create an array of objects, it is actually an operator overload to the '[]' operator.
An example for it's use would be if you wanted to make a List wrapper class.
In order to preserve the square braces functionality you would need (and want) to override the square braces operator. This is done via an indexer method.

array comparison(T) delegate NullReferenceException

I'm having a problem with the delegate not delegating...
I have an object called Tweet that has a string text and an int score. I want to sort the array of tweet objects(twtArray) in order of the score.
This is the code I have:
Array.Sort(twtArray, delegate(Tweet twt1, Tweet twt2)
{
return twt1.score.CompareTo(twt2.score); //(twt1.score - twt2.score)
});
and it throws:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Array.FunctorComparer`1.Compare(T x, T y)
Whilst debugging, I noticed that the first comparison works but in the second comparison, twt2 is null. And it can't be null because I definitely have 8 elements in the array.
I've tried reversing twt1 and twt2 as well but makes no difference.
I also tried making my own comparison method in the Tweet class but again, same thing.
Any help would be appreciated!
Also, I dont think this is a duplicate of this question: List.Sort in C#: comparer being called with null object
because i tried all the possible solutions from this but it's not working. i've also searched a lot on google :(
Even if you have a Tweet[] with 8 elements some can be null:
Tweet[] twtArray = new Tweet[8]; // all instances are null
You: The Tweet[] is of size 20 and I can see that there are 8 Tweet objects in there (with correct text and score values) in the first line of my code.
So the array's size is 20 but only 8 are initialized? (see above)
Array.Sort needs to compare all with all others.
You could prevent it in this way:
Array.Sort(twtArray, delegate(Tweet twt1, Tweet twt2)
{
if(twt1 == null && twt2 == null) return 0;
if(twt1 == null) return -1;
if(twt2 == null) return 1;
return twt1.score.CompareTo(twt2.score);
});
When you're working with an array that's only partially filled, that indicates that you don't actually want an array, you want List<T>.
Using that, you can have a collection that contains 8 items, but can be later expanded to 20 efficiently. And when you call Sort() on such list, you're not going to have any problems with nulls.

Length of string array via reflection

Is it possible to know the length of a string array - without having an object instance - via reflection?
E.g. in this case: 2.
public string[] Key
{
get { return new string[] { Name, Type }; }
}
EDIT: ok, I will not try to do this, it doesn't make much sense.
Perhaps you mean "without having the exact type of the Array". C# Arrays all derive from Array, so you can cast an Array reference to Array and use the Length property.
If you TRULY wants to reflect the property,
var type = typeof(MyClass);
var prop = type.GetProperty("Key");
var method = prop.GetGetMethod();
var body = method.GetMethodBody();
var ils = body.GetILAsByteArray();
from here you'll have to use one of the various libraries to decode bytes to IL OpCodes (for example https://gist.github.com/104001) . The OpCode you are looking for is newarr. The last push of an int32 before the newarr is the size of the array.
You have two things going on there... telling the length of an array is pretty simple once you have an array; you just call .Length (in the case of a vector).
However, you mention an instance, and you are showing an instance property; which makes me think it is the containing object you lack. In which case... no. You can't make a virtcall on a null instance. And trying to use static-call on an instance member of a class is very evil; IIRC the runtime will kick you for this.
You could, however, make it a static property just by adding the static modifier. Then you just pass in null as the instance to reflection.
I guess you mean you want to know the size of the array the property will return if it were called?
I don't think you can do it sensibly.
If the property had a conditional then it could return different sized arrays, so
you'd have to evaluate the property to know the size. Which could have side effects or be dependent on other values in the object (or statics).
Consider this one:-
static public int n;
public string[] Key
{
get {
if (n > 1)
return new string[] { "Name", "Type" };
else
return new string[] { "Name", "Type", "Cheese" };
}
}
Basically, you'd have to run the code.

Categories