I have an object which is made of many other objects! I am trying to find the value of of one of the properties (an enum) but can't.
Now, normally if I want to check if an object is null I can do
if (object == null)
but this results in the same error.
I tried
if (object.Equals(null)) and the same error.
The error message I'm getting is objectName threw exception: System.NullReferenceException: Object reference not set to an instance of an object..
I'm trying to determine if my object is instantiated or not. Now, I can stick this into a try catch, if it errors then I know it's not, but to me this feels very wrong (although I may not have a choice).
The other problem I have is this project isn't mine and is a black box to everyone and so I can't make any changes to the original object! This means, all I have is what I have got, an object which may or may not be instantiated and I need a way of telling.
Other than the try catch, do I have any other options?
EDIT
So, the object is
public partial class SaveBundleResponse
{
SaveBundleResponseHeader header;
}
public partial class SaveBundleResponseHeader
{
private SaveBundleResponseHeaderStatus status;
}
public enum SaveBundleResponseHeaderStatus
{
Success, Fail, OK, OtherStates
}
So the SaveBundleResponse is created initially, the instance is then passed through a 'workflow' style environment and each property becomes 'populated/updated' etc as it goes deeper into the workflow. However, in a few situations, the enum is never set.
The problem is, I need to know the value of the enum (or if it is null).
The code I am trying to use is
if (saveBundleResponse.Header.Status // what ever happens, it fails at this point as Status is not initiated.
if (saveBundleResponse != null)
{
var header = saveBundleResponse.Header;
if (header != null)
{
var status = header.Status;
}
}
You should be able to use something like this:
SaveBundleResponse sbr = ...;
if (sbr.Header != null && !sbr.IsDisposed)
{
//Do the work
}
This should work (if the class is not a control you can't use the IsDisposed check).
Related
Am trying to get up to speed with Code Contracts. Here is another issue that doesn't make sense to me:
This is the Invariant:
[ContractInvariantMethod]
void Invariant() {
Contract.Invariant(this._uiRoot.RowDefinitions!=null);
}
Then, in a Method is this code:
int colunmn = 0;
foreach (UIElement uiElement in row.Where(element => element!=null))
{
if (uiElement != null)
{
uiElement.SetValue(Grid.ColumnProperty, colunmn++);
uiElement.SetValue(Grid.RowProperty, _uiRoot.RowDefinitions.Count - 1);
_uiRoot.Children.Add(uiElement);
}
}
I then get a warning that _uiRoot.RowDefinitions may be null, despite the Invariant. I don't see why CodeContracts would think that if it is checked after every public method call and the constructor. The code in question is a custom form designer, and it uses the uiRoot.RowDefinitions in a number of different methods, which is why I wanted to put it into the Invariant. I thought this would be enough to stop the warnings on it.
I think invariant only runs on public property access. Is it possible to add a contract to the RowDefinitions property itself? Your invariant can't prove that property won't be null; you could call a method on that type which sets it to null after your invariant runs.
I am trying to get a StringElement's 'Value' to update in the UI when I set it after already setting up the DVC.
e.g:
public partial class TestDialog : DialogViewController
{
public TestDialog() : base (UITableViewStyle.Grouped, null)
{
var stringElement = new StringElement("Hola");
stringElement.Value = "0 Taps";
int tapCount = 0;
stringElement.Tapped += () => stringElement.Value = ++tapCount + " Taps";
Root = new RootElement("TestDialog")
{
new Section("First Section")
{
stringElement,
},
};
}
}
However the StringElement.Value is just a public field, and is only written to the UICell during initialization when Element.GetCell is called.
Why isn't it a property, with logic in the setter to update the UICell (like the majority of Elements, e.g. EntryElement.Value):
public string Value
{
get { return val; }
set
{
val = value;
if (entry != null)
entry.Text = value;
}
}
EDIT :
I made my own version of StringElement, derived from Element (basically just copied the source code from here verbatim)
I then changed it to take a class scoped reference to the cell created in GetCell, rather than function scoped. Then changed the Value field to a property:
public string Value
{
get { return val; }
set
{
val = value;
if (cell != null)
{
// (The below is copied direct from GetCell)
// The check is needed because the cell might have been recycled.
if (cell.DetailTextLabel != null)
cell.DetailTextLabel.Text = Value == null ? "" : Value;
}
}
}
It works in initial testing. However I am not sure on whether taking a reference to the cell is allowed, none of the other elements seem to do it (they only take references to control's placed within the cells). Is it possible that multiple 'live'* cell's are created based on the one MonoTouch.Dialog.Element instance?
*I say live to indicate cells currently part of the active UI. I did notice when navigating back to the dialog from a child dialog the GetCell method is invoked again and a new cell created based on the Element, but this is still a 1-1 between the element and the live cell.
For the main question:
Why does MonoTouch.Dialog use public fields for some Element options, and public properties for others?
I've been through the code, and I don't think there's a consistent reason for use of either.
The Dialog project was not part of the MonoTouch project initially - I don't think Miguel knew how useful it was going to turn out when he started wrote and grew it - I think he was more focussed on writing other apps like TweetStation at the time.
I know of several people (including me!) who have branched the code and adapted it for their purposes. I would guess at some future point Xamarin might write a 2.0 version with stricter coding standards.
Taking references to live cells
For limited use you can do this... but in general don't.
The idea of the table view is that cells get reused when the user scrolls up and down - especially in order to save memory and ui resources. Because of this is a long list, multiple elements might get references to the same cell.
If you do want to cache a cell reference then you probably should override GetCell() so that it never tries to reuse existing cells (never calls DequeueReusableCell)
Alternatively, you could try to change some code in the base Element class in order to find out if the Element has a current attached cell - this is what CurrentAttachedCell does in my branch of Dialog https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Dialog/Dialog/Elements/Element.cs (but that branch has other added functions and dependencies so you probably won't want to use it for this current work!)
I am wondering why this code works fine and comiler doesnt generate any errors or warnings?
class Program
{
static int _value;
static int MyValue
{
get { return _value; }
set { _value = 5; }
}
static void Main()
{
Console.WriteLine(Program.MyValue); //This line print 0 (defoult value of int variables)and its normal
Program.MyValue = 10; //after calling the Set accssor we will see that
Console.WriteLine(Program.MyValue); //The result is 5
Console.ReadLine();
}
is this any usefull or special thing? or could it be a technic in Property initialization? thanks in advance.
EDIT:
It seems what we have here is a Readonly Property with defoult value am I right?
The set-accessor is nothing other than a method with a parameter, the "value"-parameter. It's up to the method what it does and what it does not.
void Set__MyValue(int value){
_value=5;
}
The code is valid C#, so wouldn't cause errors or warnings.
Code in getters and setters can be anything, so can't really be statically checked - even if you do something strange like ignore the value passed into the setter, that might be exactly the right thing for your code.
Since the set statement is actually just a convenient way of specifying a full method (i.e. set_MyValue(int value)) all the normal rules of functions apply. In particular, there is no obligation to use the parameters if you don't want to.
While your example is contrived, there are plenty of situations where it makes sense to ignore the value passed in. For example, suppose you wanted to make sure a particular string property was never null. You might do something like this:
private string _myProp = string.Empty;
public string MyProp
{
get
{
return _myProp;
}
set
{
if (value == null)
{
_myProp = string.Empty;
return;
}
_myProp = value;
}
}
We ignore value if we want to, and don't otherwise.
This code is pretty valid and also can be usefull in certain scenarious . If you immagine that you want raise an event/WPF command on _value changing, log that stuff, do any other meaningful for you stuff there. Having this kind of management setting the _value directly will cause "silent" assignment, setting this _value via property can cause notifications.
I will never do something like this honestly, cause it's confusional and not clear for someone who doesn't really understand your code, but by the way it's kind of "solution" too.
Regards.
The property will be converted as 2 different methods in IL(one for set the value and the other is to return the value) and ignoring a parameter is valid in a method!
You can check this by using the tool ildasm.exe(which comes with Visual Studio).
I am trying to read value from a listbox item that is on another thread.
I tried to make a new method to run the invoke command, I can manage to send a command to the listbox like add via the invoke method but i cant seem to get a response, i cant seem to get the value of the item, i have tried a few ways, once i change it from a void to a string things start to get hairy...
thread t1 = new thread(thethread)
t1.start()
public void thethread()
{
string text = readListBoxSelected(listBox1) + " lala" ;
}
public static string readListBoxSelected(ListBox listbox)
{
if (listbox.InvokeRequired)
{
return (string)listbox.Invoke(
new Func<String>(() => readListBoxSelected(listbox))
);
}
else
{
string varText = listbox.SelectedValue.ToString();
return varText;
}
}
Above is a example of what i am trying to do.
Here is the error:
System.NullReferenceException was
unhandled by user code
Message=Object reference not set to an
instance of an object.
Source=** StackTrace:
at **.Form1.readListBoxSelected(ListBox listbox) in e:\documents and
settings\scott\my documents\visual
studio
2010\Projects*****\Form1.cs:line
133
at ***.Form1.<>c_DisplayClass5.b_3()
in e:\documents and settings\scott\my
documents\visual studio
2010\Projects******\Form1.cs:line
127 InnerException:
I imagine what is wrong is exactly what it says "Object reference not set to an instance of an object"....... All my variables seem to be declared as fair as i am aware, how can i correct this??
I get the feeling i am going about the entire thing wrongly.... 0_o
Thanks in Advance,
Scott
Try This
public static string readListBoxSelected(ListBox listbox)
{
if (listbox.InvokeRequired)
{
return (string)listbox.Invoke(
new Func<String>(() => readListBoxSelected(listbox))
);
}
else
{
if(istbox.SelectedValue != null)
return listbox.SelectedValue.ToString();
else
return String.Empty
}
}
Code looks fine, the problem seems on the SelectedValue, is it null. ???
Thanks guys,
You where correct, Problem was it was returning a null value..
I was so sure that i was selecting the item correctly i never thought it could be the problem.
Turns out the problem was two things:
1)
The way i was selecting item, i was using listbox.Selecteditem = 1 , now if i use listbox.setSelected(1,true) all is good :)
and
2)
The way i was getting the items text was wrong, listbox.SelectedValue is nothing, it dosnt do what we all imagine it to do... the call i need was listbox.Text .........
public static string readListBoxSelected(ListBox listbox)
{
if (listbox.InvokeRequired)
{
return (string)listbox.Invoke(
new Func<String>(() => readListBoxSelected(listbox))
);
}
else if(listbox.Text != null)
{
return listbox.Text.ToString();
}
else
return String.Empty;
}
public void selectListBoxItem(ListBox listbox, int num)
{
Invoke(new MethodInvoker(delegate { listbox.SetSelected(num,true); }));
}
I must say this is the most anoying thing i have ever done... Everything requires i write a delegate / invoke method for it... Everything... woudlnt something so common be supported by .net on the fly....
Seems a waist of time to write individual delegates for EVERYTHING...
Thanks guys all is working now, yesterday i couldn't foresee me getting to this point,
Overall problem was Wrong Calls, the invoke was all fine :)
Scott
EDIT:
ok it was returning NULL simply because listbox.SelectedValue isnt really the call im after to read the selectedvalue (you would think it was), if i change it to listbox1.text all works fine.... rather silly this .net object oriented stuff if i do say so....
I must say what a joke... thats kindly destroyed my faith in object oriented programming..
I understand this is not a discussion fourm but honestly the call SelectedValue.toString() should do what we all think it will do.... nope we need to use .Text to get what we require 0_o.........
I'm new in C# but not new to coding --being doing it for almost two decades--, and have a problem with properties in a custom control I'm building, which inherits from a Panel. When I put my properties, I can see them in the Designer properties list and can even set them, but when running my little application, it seems these properties values are not used. The same if I change a property programatically: no error but my control does nothing, it is like they are not properly set. However, if I do it programatically whithin the class, they do work. My guess is that something in my properties set/get stuff is not right. Please see the following code chunk of how I'm doing it:
public class ColorStrip : Panel
{
// properties
// ------------------------------------------
// size of color clusters (boxes)
private int _clusterSize = 20;
// controls if show the buttons panel
private Boolean _showButtons;
// property setters/getters
// ------------------------------------------
// clusterSize...
public int clusterSize
{
get { return _clusterSize; }
set { _clusterSize = value; }
}
// showButtons...
public Boolean showButtons
{
get { return _showButtons; }
set { Console.Write(_showButtons); _showButtons = value; }
}
....
So in my form, for instance in the load or even in a click event somewhere, if I put colorStrip1.showButtons = false; or colorStrip1.showButtons = true; whatever (colorStrip1 would be the instance name after placing the control in the form in design mode)... console.write says always 'false'; Even if I set it in the design properties list as 'true' it will not reflect the settled value, even if I default it to true, it will never change externally. Any ideas? Non of the methods get the new and externally settled property value neither, obviously the getter/setter thing is not working. Seems to me I'm not doing right the way I set or get my properties outside the class. It works only inside it, as a charm...Any help...very appreciate!
Cheers
lithium
p.s. TO CLARIFY SOLUTION:
Setting the property in this case didn't work because I was trying to use a new set value within the constructor, which seems can't get the new values since it is, well, building the thing. If I change the property value in Design mode > Property editor or in code externally to the object, say in it's parent form's load event, it will change it but readable for all methods except the constructor, of course :)
It's likely an issue of the order of execution. Your property setter just sets a variable, but doesn't actually trigger anything on the control to update the state related to this variable (e.g. adding or showing the buttons I assume).
When you set the property befre the rest of the initialization is done, the value is being used, otherwise it isn't because during the initial go the default value is still the property value.
You need to act on the setter, here's some pseudocode to illustrate:
set {
_showButtons = value;
if (alreadyInitialized) {
UpdateButtons();
}
}
Note: make sure to first set the value, then act - otherwise you end up using the old value (just like your Console.Write() is doing).
The quoted code doesn't look problematic. Are you sure you're referencing the same instance of ColorStrip? Also, check your .Designer.cs file to ensure that the code setting the property is there.
In fact, try simplifying your code by using auto-implementing properties:
public int clusterSize { get;set;}
public Boolean showButtons {get;set;}
public ColorStrip() { ... clusterSize = 20; ... }