Why ToString using "." operator - c#

Im starting the second course in computer programming and right now I have an intermediate level of C language knowledge, beginner C++ and just have started learning C# language. In C# fundamentals by Bob Tabor he uses the . as class operator eg.
Console.WriteLine(myValue); Console.ReadLine();
Where Console is the class and WriteLine is part of this class. To keep everything organised I was trying understand all the concepts of it but in one moment he converted an integer to string by using function:
myValue.ToString();
And in that point I got lost. Why he uses that logic instead of simple and organised way like:
System.ToString(MyValue);
He hasn't used the value that has to be converted as an argument. That just doesn't make any logic sense.. Am I wrong?

Every object inherits from System.Object (except object itself) in the .NET Framework. And System.Object defines a public ToString() method, therefore you can call ToString() on any object.
Console.WriteLn calls ToString on objects passed to it as argument, in order to get a string it can print.
There is no such thing as System.ToString(). System is a namespace and a method cannot exist in the global scope; it is always a member of a type. From within an object you can call the members directly, from outside you must use the dot syntax: someObject.SomeMethod(); or x = someObject.SomeProperty;. Static members are called from the type name: SomeType.SomeMethod();. Console.WriteLn(); is a good example.

The only functional difference is that Convert.ToString() handles null, while ToString() doesn't, since obj.ToString() presumes the obj is not null, whereas ToString(obj) will return String.Empty on a null object.

Every object has methods and properties, you call the method "ToString" to format the object as an string.
If you realize you are writting less than calling a system method to formart it.

Related

Casting to arbitrary non-generic return type at runtime, C#

I'm trying to make a user-friendly debug framework where users can create more debug variables as easily as possible.
I need to cast an object to the return type of my property/method (bool, int, whatever), without knowing what that return type is.
tldr: How can I return a non-generic type (in this example bool) from
public bool MyGetSetProperty {
get {
object obj = new object();
return (bool)obj;
}
}
WITHOUT specifying "return (bool)"? So something like
return (GenericThingHereThatPassesAsBool)obj;
or
return obj as MyGetSetPropertyReturnType;
----------
Detail:
I want users to be able to create new properties in this class as easily as possible - basically copying+pasting the whole code block below, and only replacing "SerializeAll" with their variable name, and the type declaration "bool" with the type they want on the field/property declarations.
In my getter, I have a couple separate checks to see if the entire debug system is enabled. If not, it returns a default value for the given variable.
[Tooltip ("Serialize ALL XML output fields?"), SerializeField]
private bool debugSerializeAll = false;
/// <summary>
/// Serialize ALL XML output fields?
/// </summary>
[DebugValue, DebugDefault (true)]
public bool SerializeAll {
get {
if (!classEnabled || !debug.debugEnabled)
return (bool)GetDefaultValue (MethodBase.GetCurrentMethod ());
return debugSerializeAll;
}
set { debugSerializeAll = value; }
}
The thing is, I can't return "default" because the default value can be overridden - see the "DebugDefault" attribute where the "default" value for this bool is actually "true", at least as far as my debug system is concerned. The method "GetDefaultValue" accommodates for that, and it returns an object that could be a string, int, bool, anything.
I'm already doing funky reflection stuff to access the MethodInfo, PropertyInfo, etc of the getter and property SerializeAll. I just can't figure out how to not have to also specify the (bool) cast on the return. Again, the goal is as little human editing as possible.
Thank you!
You should be able to do this with a cast to dynamic.
return (dynamic)GetDefaultValue (MethodBase.GetCurrentMethod ());
Bear in mind that the compiler isn't actually making this into a cast to bool. Rather, this makes the compiler ignore compile-time type-safety, and instead the program will use reflection at runtime to figure out the best way to take the value returned from GetDefaultValue and turn it into what it needs to be.
I want users to be able to create new properties in this class as easily as possible...
This is a good principle.
... basically copying+pasting the whole code block below, and only replacing "SerializeAll" with their variable name, and the type declaration "bool" with the type they want on the field/property declarations.
That totally breaks the principle you just mentioned, and results in a bunch of boilerplate code and other code smells.
In theory, you could probably create a Fody Weaver or something to add this boilerplate code upon compilation. But that's probably more work than it's worth.
I would hazard a guess that this is an "XY Problem", where you're asking how to achieve the solution that you've imagined, rather than asking how to solve the problem you're actually facing.
Why should every property in your class return a completely different value if certain private fields are set a certain way? This sounds like a big Separation of Concerns problem, where you're tasking your class with doing two completely different things. I strongly suggest you find another way to solve the problem you're trying to solve. For example, when code tries to get an instance of your class, it could go through a method that checks the classEnabled and debug.debugEnabled concepts (which probably belong in a different class), and returns an instance with the properties all set to their defaults.
Please Link click here -> How to cast Object to boolean?
or
I think you need to study for Generic class
Check if a class is derived from a generic class

Cast object into appropriate type for overloaded methods

Say I have a method that is overloaded such as void PrintInfo(Person) and void PrintInfo(Item), and so on. I try to invoke these methods by passing in an Object.
I'm wondering why it is giving me an error when I do this; aren't all classes inherited from Object? I want to avoid doing an if/switch statement where I check which type the Object is before calling the appropriate method.
What do you guys think is the best approach in this case?
All Persons are objects , but not all objects are Persons. Because of this you can pass a Person to a method that accepts an object but you can't pass an object to a method that requires a Person.
It sounds like you have some common bit of functionality between various objects that you want to use. Given this, it would be best to find either a common ancestor that has all of the functionality that you need, or an interface that they all implement (that again provides everything that you need).
In the case of printing, you may just need the ToString method. In that case, you can just have the method accept an object and call ToString on it. (That's what many print methods do, such as Console.WriteLine.
You need to understand that because C# is a statically typed language (barring dynamic) the particular overload that is chosen (called overload resolution) is determined at compile time, not run time. That means that the compiler needs to be able to unequivocally determine what type your argument is. Consider:
Object foo;
foo = "String";
foo = 5;
PrintInfo(foo); // Which overload of printinfo should be called? The compiler doesn't know!
There are a few ways to solve this- making foo of type dynamic is one- that will cause the correct overload to be chosen at compile time. The problem with that is that you lose type safety- if you don't have an appropriate overload for that type, your application will still compile but will crash when you try to print the unsupported type's info.
An arguably better approach is to ensure that foo is always of the correct type, rather than just Object.
As #Servy suggests, another approach is to attach the behavior to the type itself. You could, for instance, make an interface IHasPrintInfo:
public interface IHasPrintInfo { String PrintInfo { get; } }
and implement that interface on all items whose info you might print. Then your PrintInfo function can just take an IPrintInfo:
public void PrintInfo(IPrintInfo info) {
Console.WriteLine(info.PrintInfo);
}
here its ambiguate for compiler; compiler can't figure out which version of method (Person/Item) you are intended to call.

Function Parameter type determined at runtime?

Is it in anyway possible ( preferably without using any third party libs), to create a function whose type is determined at runtime in C#?
e.g
public static void myfunc(var x)
{
System.Windows.Forms.MessageBox.Show(x); //just an example
}
NOTE: I want the runtime to determine the type of the parameter and do not want to later cast the parameter to another type, as would be necessary if I use generics. e.g I don't want:
myfunc<T>(T x)
// and then :
MessageBox.Show((string)m);
UPDATE:
I am actually making a function parser for my programming language, which translates to C# code. In my language, I wanted the parameter types to be determined at runtime always. I was looking for some good C# feature for easy translation.
e.g
in my language syntax:
function msg << x
MessageBox.Show x
end
needed to be translated to something that didn't ask for a type at compile time, but would need one at runtime.
e.g
public static void msg(var x)
{
System.Windows.Forms.MessageBox.Show(x);
}
The keyword introduced for runtime binding in C# 4 is dynamic.
public static void myfunc(dynamic x)
This allows you to make assumptions about x that are unchecked at compile time but will fail at runtime if those assumptions prove invalid.
public static void MakeTheDuckQuack(dynamic duck)
{
Console.WriteLine(duck.Quack());
}
The assumption made here is that the parameter will have a method named Quack that accepts no arguments and returns a value that can then be used as the argument to Console.WriteLine. If any of those assumptions are invalid, you will get a runtime failure.
Given classes defined as
class Duck
{
public string Quack()
{
return "Quack!";
}
}
class FakeDuck
{
public string Quack()
{
return "Moo!";
}
}
And method calls
MakeTheDuckQuack(new Duck());
MakeTheDuckQuack(new FakeDuck());
MakeTheDuckQuack(42);
The first two succeed, as runtime binding succeeds, and the third results in an exception, as System.Int32 does not have a method named Quack.
Generally speaking, you would want to avoid this if possible, as you're essentially stipulating that an argument fulfill an interface of some sort without strictly defining it. If you are working in an interop scenario, then perhaps this is what you have to do. If you are working with types that you control, then you would be better served trying to achieve compile time safety via interfaces and/or base classes. You can even use different strategies (such as the Adapter Pattern) to make types you do not control (or cannot change) conform to a given interface.
If you need to know the type... then you need to know the type. You can't have your cake and eat it too.
First off, the cast in your example is unnecessary as all objects implement ToString(). Instead of telling us what you think you need, tell us what problem you are trying to solve. There is almost certainly a solution either via generics or the use of the dynamic keyword (though dynamic is rarely needed), but we need more info. If you add more I'll update this answer.
You could use a type of object or, if you don't know how many items are available, you could use a params object array, i.e. params object[] cParams.

Confusion regarding boxing of value types

In the following code...
int i=5;
object o = 5;
Console.WriteLine(o); //prints 5
I have three questions:
1) What additional/useful functionality is acquired by the 5 residing in the variable o that the 5 represented by the variable i does not have ?
2) If some code is expecting a value type then we can just pass it the int i , but if its expecting a reference type , its probably not interested in the 5 boxed in o anyway . So when are boxing conversions explicitly used in code ?
3) How come the Console.WriteLine(o) print out a 5 instead of System.Object ??
What additional/useful functionality is acquired by the 5 residing in the variable o that the 5 represented by the variable i does not have ?
It's rare that you want to box something, but occasionally it is necessary to do so. In older versions of .NET boxing was often necessary because some methods only worked with object (e.g. ArrayList's methods). This is much less of a problem now that there is generics, so boxing occurs less frequently in newer code.
If some code is expecting a value type then we can just pass it the int i, but if its expecting a reference type, its probably not interested in the 5 boxed in o anyway . So when are boxing conversions explicitly used in code ?
In practice boxing usually happens automatically for you. You could explicitly box a variable if you want to make it more clear to the reader of your code that boxing is happening. This might be relevant if performance could be an issue.
How come the Console.WriteLine(o) print out a 5 instead of System.Object ??
Because ToString is a virtual method on object which means that the implementation that is called depends on the runtime type, not the static type. Since int overrides ToString with its own implementation, it is int.ToString that is called, not the default implementation provided by object.
object o = 5;
Console.WriteLine(o.GetType()); // outputs System.Int32, not System.Object
1) On its own, there is not much point. But imagine you wish to store something in a generic way, and you don't know whether that thing is a value or an object. With boxing, you can convert the value into an object, and then treat everything as an object. Wihtout it, you would need a special case to be able to hold a value or an object. (THis is most useful in containers such as lists, allowing you to mix values like 5 with references to objects like a FileStream).
2) Boxing conversions usually only happen implicitly, except in example code illustrating boxing.
3) The WriteLine code probably calls the virtual Object.ToString() method. If the class of the Object it calls this on does not override ToString, then it will call the base class (object) implementation, but most types (including System.Int although int is a value type, it is still derived from System.Object) override this to provide a more useful context-specific result.
What additional/useful functionality is acquired by the 5 residing in the variable o that the 5 represented by the variable i does not have ?
There is no additional functionality acquired by a boxed value type, apart from the fact that it can be passed by referenced to code that requires that.
So when are boxing conversions explicitly used in code ?
I can't spontaneously think of a scenario when you would need to explicitly box an int to an object, since there is always an implicit conversion in that direction (although I would not be surprised if there are cases when an explicit conversion is required).
How come the Console.WriteLine(o) print out a 5 instead of System.Object ??
It calls ToString on the object passed. In fact, it starts by trying to convert the object to an IFormattable and, if successful (which it will be in the case of an int) then calls the ToString overload that is defined in that interface. This will return "5".
Additional functionality: The object is a full-fledged object. You can call methods on it and use it as you would any other object:
System.Console.WriteLine("type: {0}", o.GetType());
System.Console.WriteLine("hash code: {0}", o.GetHashCode());
The int variable is a value type, not an object.
XXX: This is incorrect; see comments. I would venture instead that the one difference in how you might use the two is that object o = 5 is nullable (you can set o = null), while the value type is not - if int i = 5, then i is always an int.
Explicit boxing: As you said, the boxed version is used by coding manipulating objects as objects rather than integers in particular. This is what enables non-type-safe generic data structures. Now that type-safe generic data structures are available, you are unlikely to be doing much casting and boxing/unboxing.
Why "5": Because the object knows how to print itself using ToString().

Why should anonymous types cannot be passed around methods?

What is the design decision to lean towards not returning an anonymous types from a method?
You can return an instance of an anonymous type from a method - but because you can't name it, you can't declare exactly what the method will return, so you'd have to declare that it returns just object. That means the caller won't have statically typed access to the properties etc - although they could still pass the instance around, access it via reflection (or dynamic typing in C# 4).
Personally I would quite like a future version of C# to allow you to write a very brief class declaration which generates the same code (immutable properties, constructor, Equals/GetHashcode/ToString) with a name...
There is one grotty hack to go round it, called casting by example. I wouldn't recommend it though.
Because an anonymous type has no name. Therefore you cannot declare a return type for a method.
Because C# is statically typed language and in a statically typed language the return type of a method needs to be known at compile time and anonymous types have no names.
How can you use your type inside your method if the definition is only in the call of the method ?
It's not javascript.
A lot of answers heere seem to indicatie that it is not possible because of the current syntax and rule. But the question is about changing them. I think it would be possible, but a little complicated and resulting in an awkward (error-prone) syntax. Like
var f() { return new { A = "*", B = 1 }; }
var x = f();
The question is whether this adds sufficient value to the language to make it worth it.
At least up to 3.5, anonymous types are actually resolved at compile time, and this would be impossible (or quite hard) to do with anonymous method signatures.

Categories

Resources