|
Can anybody please tell me how does a Nullable<T> work in following scenario, where I have:
int? tmp = 10;
tmp = null;
Console.WriteLine(tmp.ToString());
Console.WriteLine(tmp.GetType());
The NRE for GetType() call seems fine but I just don't get how ToString() (and ofcourse GetHashCode() and Equals(T) ) works. I know these methods have been overridden in Nullable<T> struct from System.Object where as GetType() couldn't (becuase that is not virtual ). But since ToString() is an instance method and I am explicitely setting temp = null , how does the call get resolved?
Even if I assume temp = null sets the T @value field in Nullable<T> struct and not the instance itself, it doesn't seem possible since @value would be of type System.Int32 which can't be set to null in the first place, hence we have Nullable<int> ?
I suspect this has something to do with "Type handle" reference that resides as a part of an instance but not sure how it works given that instance itself is null .
Any explanation would be greatly appreciated.
Whether I think I can, or think I can't, I am always bloody right!
|
|
|
|
|
This gets complex...
ToString is overridden, as you say - it has to be, because a nullable type "encapsulates" the ValueType it holds, and if it wasn't then it would never work!
So when you call ToString on the tmp variable, it checks the type of variable - Nullable<int> - and calls the Nullable<T> version of ToString, without worrying about the content:
IL_002a: ldloca.s tmp
IL_002c: constrained. valuetype [mscorlib]System.Nullable`1<int32>
IL_0032: callvirt instance string [mscorlib]System.Object::ToString()
IL_0037: call void [mscorlib]System.Console::WriteLine(string)
But...GetType isn't overridden - which means that the default object version must be called, which takes a Reference parameter, not a Value type. Which means that the Nullable<T> value type needs to be boxed to convert it, and it's the boxing operation that throws the NullReferenceException, not the GetType call:
IL_003d: ldloc.0
IL_003e: box valuetype [mscorlib]System.Nullable`1<int32>
IL_0043: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0048: call void [mscorlib]System.Console::WriteLine(object)
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Your right, that is complex!
Regards,
Rob Philpott.
|
|
|
|
|
As you fully understand when creating int? you actually creates a Nullable<int>, which is a structure that actually never null. In fact it has a value member that actually holds the value - that can be null.
Now, when you call ToString you call an overridden version, that has this code:
public override string ToString()
{
if (!this.HasValue)
{
return "";
}
return this.value.ToString();
}
That explains why it works even you had expected a null reference exception...
With GetType is a different story, it is derived from object and never overridden by Nullable<t>, so it will be executed on the internal value which is null, therefor it fails!
(GetHashCode and Equals are also overridden)
You may use some decompiler to see the whole class...)
I'm not questioning your powers of observation; I'm merely remarking upon the paradox of asking a masked man who he is. (V)
|
|
|
|
|
Kornfeld Eliyahu Peter wrote: it has a value member that actually holds the value - that can be null But in case of Nullable<int> , the type of that value member would be int , right? And since int itself is a structure, it can't hold null , can it?
Whether I think I can, or think I can't, I am always bloody right!
|
|
|
|
|
No, but the Nullable<T> type has an object which holds the "T" value, and a flag which says "This is null".
The actual object doesn't hold null - Nullable<T> sets the flag when you try instead.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
ok, that makes sense, thanks!
Whether I think I can, or think I can't, I am always bloody right!
|
|
|
|
|
Good question - I like it.
Regards,
Rob Philpott.
|
|
|
|
|
You flatter me, SIR!
Whether I think I can, or think I can't, I am always bloody right!
|
|
|
|
|
|
Nobody here is going to go to a random website and download a random RAR / ZIP file to look at your code.
If you want us to see it, post the relevant fragments only here and explain what you are doing, what you expect to get, why you expect to get it, and what you do get.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Im facing "attepted to divide by zero" exception in my audio steganography code made in c#.
I think the error is near the line:
// The key must be repeated, until every bit of the message has a key byte.
double countKeyCopies = messageLengthBits / keyLength;
please provide the solution.
Krrish
|
|
|
|
|
Well, based on the code you have provided:
if (keyLength != 0)
{
double countKeyCopies = messageLengthBits / keyLength;
... Is about the only advice we can give...
If I was you, I'd be looking at why keyLength is zero, not trying to work round the fact. And that's elsewhere in your code.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
hey OriginalGriff,
Thanks for the solution
After doing that change, im facing new problem....
if (m_Stream.Position >= m_Stream.Length)
{
Console.Write("before ex");
throw new Exception("Invalid file format");
}
here this exception is fired, why position of stream is exceeding the length?
Please help...
(and i will now onwards use the key with nonzero length )
Krrish
|
|
|
|
|
This may come as a surprise to you, but I can't see your screen, access your HDD, or read your mind...
I would suspect it's related to your previous problem, and that you are just "papering over the cracks" in something that is fundamentally flawed elsewhere - what you are seeing here are symptoms, but they aren't necessarily the problem.
It's similar to you driving down the road and noticing a lot of abnormal road noise. So you turn the radio up. Then you notice that it's really difficult to steer, so you decide to use long straight roads only.
The problem is that one of your tires was flat and has started to fall apart completely. And if you don't stop and fix it you are going to have even more problems in a minute!
Stop trying to fix symptoms, and look for the source of the problem!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Ya bro.... i understand what u r telling, bt im new at c# coding so facing problems.
|
|
|
|
|
Please, don't use textspeak here - it can really annoy people, and that reduces your chances of getting a helpful answer.
I can't help you fix your code - I don't have a clue what you have written, and I couldn't run it if I did as I haven't got your data either - so it's going to be up to you.
Start with the "original" code - I'm pretty sure you didn't write it all - and look ate what is happening with the data there. Then look at what the code you added does to that data: that should give you clues as to what you are doing wrong.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Because you read past the end of the file?
Without seeing the bigger code that this is a part of it's impossible to tell you what you did wrong.
|
|
|
|
|
Have you attempted to retrieve anything from the stream yet? If not, add the following beforehand:
m_Stream.Position = 0;
|
|
|
|
|
I have an application that calls the run prompt, but the OS puts the run prompt in a strange location. I can't seem to identify the hWnd of the window so that I can use pin invoke commands to move it?
Has anyone ever been able to identify the run prompt window and send a command to the OS to move it?
64bit
c:\Windows\SysWOW64\rundll32.exe shell32.dll,#61
32bit
c:\Windows\System32\rundll32.exe shell32.dll,#61
|
|
|
|
|
Ummm....why?
It's a Window that belongs to Explorer.
Also, anything you do in the Run window can be done with Process.Start(). What's with the obsession with the Run window?
|
|
|
|
|
Explorer is putting the prompt in an odd location and I would like to be able to control that.
I've created a GUI toolbar for server 2012, which is why process.start isn't an option in this case as a replacement for a GUI prompt.
|
|
|
|
|
turbosupramk3 wrote: xplorer is putting the prompt in an odd location and I would like to be able to control that.
There is a problem in Explorer that is causing it. I have no idea what the cause of the problem is though. What I've done to "fix" it is to login at the console as a new user that has never logged in on the machine before. Hit Win-R to bring up the window and it always shows up in the proper place. I then logout and back in again as the user affected, and it's fixed.
I've only seen this happen twice - ever.
You're trying to code around a problem, not fixing the problem.
turbosupramk3 wrote: I've created a GUI toolbar for server 2012, which is why process.start isn't an option
That makes no sense. If you're replacing something (you don't specify what) then that makes Process.Start even more effective as a solution.
|
|
|
|
|
It makes perfect sense. I've created a GUI tool bar since server 2012's version sucks. Part of that is familiarity, and one of the buttons I have calls the run prompt via the code I posted in my first post, which does use process.start behind the scenes to make that call. Click on the button for that and up the old familiar run prompt comes. I do not know why Windows places it on screen where it does, but I'd like to move it dependent on where a user puts the tool bar at on screen and not have that static odd ball location.
Now, do you know how I can move this Explorer shell window? Spy++ can see a window handle for it and I can drag it around the screen manually ... usually when I can do something manually, I can do it programmatically.
|
|
|
|
|
Get the name of the window, verify it in Spy++, and you can find it with this[^].
Once you have the handle you can set it's position with SetWindowPos[^].
|
|
|
|