| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| If we have something like this object x = null; MessageBox.Show(x.ToString()) we get an error. That kindof makes sense but there is no reason the behaviour couldn't be to return an empty string. When we call x.ToString we are really calling a function like this: class Object { public static string ToString(object* Instance) { //code to convert the object pointer to a string } } Why can't the compiler just pass in Instance as a null and let the code sort it out. If the code wants to throw an error then it can but if it wants to do something more useful then it can. This would be useful in some cases (I admit they are rare but the ToString example above could potentially be used quite often). I can think of a few cases where this could be useful, eg: string x = null; MessageBox.Show(x.IsNullOrEmpty.ToString()) MessageBox.Show(x.Length.ToString()) //<--- shows zero DateTime? y; MessageBox.Show(y.IsValid) The interesting thing is you can define extention methods that do work on null objects, eg static class Extensions { public static bool IsSomething(this string s) { return !string.IsNullOrEmpty(s); } public static string ToStringIgnoreNull(this object s) { if(s == null) return string.Empty; return s.ToString(); } } Then use it like this: string x = null; if (x.IsSomething()) MessageBox.Show(x) or object x = null; MessageBox.Show(x.ToStringIgnoreNull()) Any comments? Cheers, Michael |
|
#2
| |||
| |||
| "Michael C" <mikec@nospam.com> wrote in message news:u7PSk0BCJHA.3392@TK2MSFTNGP03.phx.gbl... > [...] When we call x.ToString we are really calling a function like this: > > class Object > { > public static string ToString(object* Instance) > { No, not really. You can do that with extension methods (as you already point out at the end of your message), but the real ToString is not static; it is a virtual method that can be overridden in child classes: class Object { public virtual string ToString() { return this.GetType().Name; } } This can't work if the object is null. |
|
#3
| |||
| |||
| Even if you declare an object, it doesn't really exist yet until you have initialized it and the compiler has not set aside any space for it. To say, "Look at the space for this object that I have not created yet and tell me what it says" would naturally throw an error. What might be possible (though I wouldn't know how to do it) would be to define behaviors for your compiler. If x is null, then the compiler or language could return something useful (instead of crashing or running off into oblivion). God knows that happens to me plenty! "Michael C" wrote: > If we have something like this > > object x = null; > MessageBox.Show(x.ToString()) > > we get an error. That kindof makes sense but there is no reason the > behaviour couldn't be to return an empty string. When we call x.ToString we > are really calling a function like this: > > class Object > { > public static string ToString(object* Instance) > { > //code to convert the object pointer to a string > } > } > > Why can't the compiler just pass in Instance as a null and let the code sort > it out. If the code wants to throw an error then it can but if it wants to > do something more useful then it can. This would be useful in some cases (I > admit they are rare but the ToString example above could potentially be used > quite often). I can think of a few cases where this could be useful, eg: > > string x = null; > MessageBox.Show(x.IsNullOrEmpty.ToString()) > MessageBox.Show(x.Length.ToString()) //<--- shows zero > DateTime? y; > MessageBox.Show(y.IsValid) > > The interesting thing is you can define extention methods that do work on > null objects, eg > > static class Extensions > { > public static bool IsSomething(this string s) > { > return !string.IsNullOrEmpty(s); > } > public static string ToStringIgnoreNull(this object s) > { > if(s == null) return string.Empty; > return s.ToString(); > } > } > > Then use it like this: > > string x = null; > if (x.IsSomething()) MessageBox.Show(x) > > or > > object x = null; > MessageBox.Show(x.ToStringIgnoreNull()) > > Any comments? > > Cheers, > Michael > > > > > > |
|
#4
| |||
| |||
| "jp2msft" <jp2msft@discussions.microsoft.com> wrote in message news:8D2A44C2-94FA-428F-A3A2-1F077B844B0D@microsoft.com... > Even if you declare an object, it doesn't really exist yet until you have > initialized it and the compiler has not set aside any space for it. The bulk of the object does exist even before you declare the object. Generally the actual code will be greater than the object itself (in size) and all of the code exists and is ready to call before an instance is created. > To say, "Look at the space for this object that I have not created yet and > tell me what it says" would naturally throw an error. There is no reason calling a function on a null object *has* to raise an exception, the designers of C# just designed it that way. They actually needed to put an extra check in to stop it working. Basically when you call, say, object.ToString you end up calling a global function ToString where the pointer to the object is passed in, ie x.ToString(); translates to (under the hood of course) public static string ToString(object* pObject) { //convert pObject to sring } I'm sure it's more complicated than that but that's the basic idea. The compiler does the null check before the static function is called but there is no reason that it needs to. It can easily call the static ToString function and let that function decide whether to allow nulls or not. Michael |
|
#5
| |||
| |||
| "Alberto Poblacion" <earthling-quitaestoparacontestar@poblacion.org> wrote in message news:e8bnSYCCJHA.4368@TK2MSFTNGP06.phx.gbl... > No, not really. You can do that with extension methods (as you already > point out at the end of your message), but the real ToString is not > static; it is a virtual method that can be overridden in child classes: Technically the real ToString is not static, it's global. But as C# doesn't have global functions I wrote it as static. > class Object > { > public virtual string ToString() > { > return this.GetType().Name; > } > } > > This can't work if the object is null. Yes it can because the type tells you whether to call the original ToString or the overridden ToString, eg object x = null; x.ToString(); //<-- calls the ToString defined by object MyClass x = null; x.ToString(); //<-- calls the ToString override on MyClass being that the real to string function looks like this: public static String ToString(MyClass* Value) { } Then it is possible to call on a null reference becase null can be passed in to the Value parameter. Michael |
|
#6
| |||
| |||
| On Wed, 27 Aug 2008 19:27:45 -0700, Michael C <mikec@nospam.com> wrote: > "Alberto Poblacion" <earthling-quitaestoparacontestar@poblacion.org> > wrote > in message news:e8bnSYCCJHA.4368@TK2MSFTNGP06.phx.gbl... >> No, not really. You can do that with extension methods (as you already >> point out at the end of your message), but the real ToString is not >> static; it is a virtual method that can be overridden in child classes: > > Technically the real ToString is not static, it's global. But as C# > doesn't > have global functions I wrote it as static. No, Object.ToString() is not static, and it's not global. It's a virtual instance method in the Object class. Every type inherits Object and so every object has the ToString() method. You are right that C# doesn't have global functions, and that includes even Object.ToString(). >> class Object >> { >> public virtual string ToString() >> { >> return this.GetType().Name; >> } >> } >> >> This can't work if the object is null. > > Yes it can because the type tells you whether to call the original > ToString > or the overridden ToString, eg No, it can't. You cannot use any instance member of a class with a null reference. In the case of ToString(), it's particularly problematic because it's a virtual method and you need an instance to get at the v-table. But even for non-virtual members the run-time requires an actual instance. In C++, for a non-virtual member, you could actually call the member with a null reference. But even in C++ you can't call a virtual function with a null reference. There's just no way that what you'd want to work could work, because ToString() is virtual. > object x = null; > x.ToString(); //<-- calls the ToString defined by object See above. It just can't work. > MyClass x = null; > x.ToString(); //<-- calls the ToString override on MyClass See above. This _definitely_ can't work. Overrides are handled via a v-table that is referenced from the object instance. No object instance, no v-table, no way to call the method. There'd be no way for the run-time to distinguish which version of the ToString() method should be called, because static typing has nothing to do with choosing the implementation for virtual methods. For example, given that: String x = "5"; Object obj = x; obj.ToString(); winds up calling the String.ToString() implementation, what should happen if you have: String x = null; Object obj = x; obj.ToString(); To be consistent, it should call String.ToString(). But how is it to know that should happen? > being that the real to string function looks like this: > > public static String ToString(MyClass* Value) > { > } The real ToString() method doesn't look anything like that. Pete |
|
#7
| |||
| |||
| On Wed, 27 Aug 2008 19:20:11 -0700, Michael C <mikec@nospam.com> wrote: > [...] > There is no reason calling a function on a null object *has* to raise an > exception, That's only partly true. For virtual methods, it _does_ have to raise an exception. > the designers of C# just designed it that way. I believe that this is a run-time rule. You can't call an instance method on a null reference in C++/CLI either. > They actually > needed to put an extra check in to stop it working. Basically when you > call, > say, object.ToString you end up calling a global function ToString where > the > pointer to the object is passed in, That's just not true. > [...] > I'm sure it's more complicated than that but that's the basic idea. The > compiler does the null check before the static function is called There's no static function, and it's not the compiler generating the code to do the check. It's part of the run-time. > but there > is no reason that it needs to. It can easily call the static ToString > function and let that function decide whether to allow nulls or not. No, it can't. Pete |
|
#8
| |||
| |||
| "Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message news p.ugksz6s58jd0ej@petes-computer.local...> No, Object.ToString() is not static, and it's not global. I'm loathe to reply to you peter as I find you can be quite rude (and usually very negative and unpleasant) but here goes for now. Actually that is wrong, every function under the hood is global. It has a location in memory and any code in the current process can call that function. The C# IDE tricks us into thinking it's instance or static or private or whatever. > It's a virtual instance method in the Object class. Every type inherits > Object and so every object has the ToString() method. You are right that > C# doesn't have global functions, and that includes even > Object.ToString(). I'm talking about under the hood at the assembly level. > No, it can't. You cannot use any instance member of a class with a null > reference. In the case of ToString(), it's particularly problematic > because it's a virtual method and you need an instance to get at the > v-table. But even for non-virtual members the run-time requires an actual > instance. There is no reason this can't be worked around. > For example, given that: > > String x = "5"; > Object obj = x; > > obj.ToString(); > > winds up calling the String.ToString() implementation, what should happen > if you have: > > String x = null; > Object obj = x; > > obj.ToString(); Simple, it calls the Object.ToString. > To be consistent, it should call String.ToString(). But how is it to know > that should happen? Obviously it should call Object.ToString. >> being that the real to string function looks like this: >> >> public static String ToString(MyClass* Value) >> { >> } > > The real ToString() method doesn't look anything like that. Really? What does it look like then peter? Michael |
|
#9
| |||
| |||
| "Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message news p.ugks72158jd0ej@petes-computer.local...> That's only partly true. For virtual methods, it _does_ have to raise an > exception. No, it can do whatever the designers decide it can do. They could have called the ToString method if they had wanted to. Possibly there are disadvantages but say it is not possible is just plain wrong. > That's just not true. Oh yes it is (see, I can disagree with no detail too :-) > There's no static function, Static was not the best choice of words but I've already explained why I used that term. I'd repeat my explanation but it appears you've missed it a couple of times already. > and it's not the compiler generating the code to do the check. It's part > of the run-time. Big deal, there's still a compiler and the compiler could do whatever the designers want. > No, it can't. Oh yes it can stoopid. > > Pete |
|
#10
| |||
| |||
| On Wed, 27 Aug 2008 22:59:54 -0700, Michael C <mikec@nospam.com> wrote: > "Peter Duniho" <NpOeStPeAdM@nnowslpianmk.com> wrote in message > news p.ugksz6s58jd0ej@petes-computer.local...>> No, Object.ToString() is not static, and it's not global. > > I'm loathe to reply to you peter as I find you can be quite rude (and > usually very negative and unpleasant) but here goes for now. You only find me "very negative and unpleasant" because you tend to post things that don't make sense, which I then find myself correcting. It's unfortunate that you don't handle disagreement and critique any better than you do. Suffice to say, I don't go out of my way to upset you; you just take it upon yourself to interpret things that way. Witness the fact that in spite of me not writing anything significantly different from what Alberto's written, you've already got that big chip sitting up on your shoulder. You're just itching for a fight. > Actually that is wrong, every function under the hood is global. If that's true, then the term "global" is meaningless. If the word can't be used to distinguish one kind of method from another, what's the point of using it? That said, using more widely accepted definitions of "global", it's not true at all that "every function under the hood is global". The word "global" refers to identifiers that require no qualification in order to be resolved. It doesn't even make sense to talk about "global" with respect to "under the hood", because "global" is an artifact of the higher-level language being used. In C#, there are no globals. Period. Everything requires qualification, being contained at a minimum inside a class that's inside a namespace. > It has a > location in memory and any code in the current process can call that > function. The C# IDE tricks us into thinking it's instance or static or > private or whatever. No. If you were talking about C++, that would not be far from the truth. But for managed code, the run-time is a lot more involved, while the C# compiler leaves these things to the run-time. The C# compiler isn't "tricking us" about anything. >> It's a virtual instance method in the Object class. Every type >> inherits >> Object and so every object has the ToString() method. You are right >> that >> C# doesn't have global functions, and that includes even >> Object.ToString(). > > I'm talking about under the hood at the assembly level. I suggest you take a look at the code generated by the C# compiler. You would find it educational. >> No, it can't. You cannot use any instance member of a class with a null >> reference. In the case of ToString(), it's particularly problematic >> because it's a virtual method and you need an instance to get at the >> v-table. But even for non-virtual members the run-time requires an >> actual >> instance. > > There is no reason this can't be worked around. In C#? Yes, there is. The C# compiler has no control over the rules the run-time imposes. Even more generally, you simply cannot call a virtual method without an instance. You couldn't even do what you're talking about in plain, unmanaged C++. If you still think you can call a virtual method without an instance, I encourage you to post the C++ code that would do so. >> For example, given that: >> >> String x = "5"; >> Object obj = x; >> >> obj.ToString(); >> >> winds up calling the String.ToString() implementation, what should >> happen >> if you have: >> >> String x = null; >> Object obj = x; >> >> obj.ToString(); > > Simple, it calls the Object.ToString. > >> To be consistent, it should call String.ToString(). But how is it to >> know >> that should happen? > > Obviously it should call Object.ToString. Um, no. That's far from obvious. Even aside from the inconsistency issue I pointed out, the fact is that you need to decide when you design the language: are you going to use static typing or polymorphism to decide which method to call? If you use static typing, then the compiler gets to decide which method to call, and that has to be based on the type of the variable used. That means that in the first example I gave, "obj.ToString()" is going to call Object.ToString() even though the type of the instance is actually String. Whether you like it or not, that's completely contrary to the whole point of making ToString() virtual in the first place. Which means that the language might as well not have virtual members. Now, one can certainly design a language without virtual members. But that's not C#, nor is it any other widely used OOP language. Virtual members are a major component of what makes OOP so powerful. So, maybe you decide you'd rather use polymorphism to decide which method to call. That means that you need to look at the actual instance to decide which method to call. But to do that, you need an instance and of course instances exist only at run-time so the compiler cannot be involved in making the decision at all. So which is it going to be? Cripple the OOP language? Or disallow calling of virtual methods with a null reference? >>> being that the real to string function looks like this: >>> >>> public static String ToString(MyClass* Value) >>> { >>> } >> >> The real ToString() method doesn't look anything like that. > > Really? What does it look like then peter? Alberto already posted it. Was there something about that you had trouble understanding? Pete |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.