What is the significance of the ToString() method? - c#

Could someone please explain this for me, how this even work??
How is it even possible to return anything out of ToString(), without creating an actual method?
using System;
namespace ConsoleApplication4
{
class Person
{
private string name;
private int age;
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
**/*
* What is ToString() method?
* What I am overriding Here?
*/**
public override string ToString()
{
return "Name= " + Name + " Age=" + Age;
}
}
class Sample
{
static void Main(string[] args)
{
Person P1 = new Person();
P1.Name = "ABC";
P1.Age = 21;
Console.WriteLine(P1.ToString());
Console.ReadLine();
**//Ouput Name = ABC Age = 23**
}
}
}

All classes and structs in C# derive implicitly from System.Object. You are overriding Object.ToString.
In C#, when you write:
class Person
{
It's effectively the same as writing
class Person : System.Object
{
How is it even possible to return anything out of ToString(), without creating an actual method?
If you don't override ToString, you'll get the default implementation provided by System.Object.ToString().
The implicit base class being System.Object is documented in 4.2.2 of the C# language spec:
The object class type is the ultimate base class of all other types. Every type in C# directly or indirectly derives from the object class type.
The keyword object is simply an alias for the predefined class System.Object.
Note that it's slightly different with a custom struct, since value types derive from System.ValueType, but System.Object is still part of the inheritance hierarchy.
This is documented in 4.1.1 of the C# language spec:
All value types implicitly inherit from the class System.ValueType, which, in turn, inherits from class object. It is not possible for any type to derive from a value type, and value types are thus implicitly sealed (ยง10.1.1.2).
Note that System.ValueType is not itself a value-type. Rather, it is a class-type from which all value-types are automatically derived.

how is it even possible to return anything out of ToString(), without creating an actual method
The default implementation of Object.ToString() is simply:
return GetType().ToString();
This returns the (unqualified) name of the type. If you had not overridden it on your Person class, then it would have returned "Person".
Subclasses are free to override this method to return a more useful string, which might include some of the object's state, or even a human-friendly representation of the object. (DateTime does this, for example.)

public override string is creating a method, it just happens to already exist, thus the override keyword is used to denote that you are redefining a method in the parent class (System.Object).
More info here: http://msdn.microsoft.com/en-us/library/system.object.aspx
Because all classes in the .NET Framework are derived from Object,
every method defined in the Object class is available in all objects
in the system. Derived classes can and do override some of these
methods, including:
Equals - Supports comparisons between objects.
Finalize - Performs cleanup operations before an object is automatically reclaimed.
GetHashCode - Generates a number corresponding to the value of the object to support the use of a hash table.
ToString - Manufactures a human-readable text string that describes an instance of the class.

Related

c# type of an object when using derived class

Having the following code:
class TrxBase
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
class Trx : TrxBase
{
public string Prop3 { get; set; }
}
static void Print(TrxBase trx)
{
if (trx is Trx trx1)
{
Console.WriteLine(trx1.Prop3);
}
else
{
Console.WriteLine("no match");
}
}
static void Main(string[] args)
{
Trx t = new Trx();
t.Prop1 = "prop 1";
t.Prop3 = "prop 3";
Print(t);
}
The code from above prints "prop 3". From what I knew. in the Print method, the object will be read as an TrxBase one. And if this is the case, where is the Prop3 property saved? How does the program knows that my parameter is actually an Trx object?
You need to distinguish between compile time types (those that e.g. determine which overload of a method to call) and runtime types (which are used by e.g. reflection). Whatever contortions you go through with a particular object1 (casting it to a base type, etc) doesn't change the runtime type of the object.
So just because you're passing t to Print which asks for a TrxBase, it doesn't change t into a TrxBase.
And if, inside Print, it tests for and determines that it's a Trx, it's perfectly valid for it to cast it back to that type (hidden inside the pattern matching syntax) and start treating it as the type it truly is (although, of course, it could be a type even more derived from Trx.
Bonus reading: Eric Lippert's Representation and Identity
1Provided you understand that reference-changing conversions give you a new object. This is also further explained in the bonus reading above.
This is how C# works, when you pass derived type object to a method with parameter with base type object compiler simply takes this derived object and interprets it like it is base.
In your case you are passing derived (Trx) object to method with TrxBase parameter. So now in the scope of Print(TrxBase trx) , trx will be treated like it is TrxBase, but then you are using pattern matching to determine if this trx can be reprsented into more derived Trx object type, which in your case is true, can and therefore prints prop 3.
It is possible to cast derived type to more base type, but the other way will result into InvalidCastException coming from CLR. Because if you think about it - lets say you allocate new object of type TrxBase, CLR allocator will allocate such object on the heap (or the stack if value type) with all the needed properties this object has. Now if you request from CLR to cast this specific object to something more specific you are ultimately requesting this specific memory layout to change into another (adding fields, properties and such from your specific object) which CLR does not support.

Why is equals method on object class virtual?

I was wondering why is Object.Equals(Object obj) virtual. I understand that we can override that method and write our own code for checking equality instead of the base Object.Equals(Object obj) method that checks only reference equality.
What I say is why override it when i can implement my own new method in my defined type? Is there any specific reason?
You would override it for the same reason you would want to override any method rather than hiding it with a new method in a derived class: because of polymorphism. You don't know how your derived class is going to be used by other code which only might know about the base class.
Clients may not even know that you've overridden the class at all, but they do know that they can call Equals on your instances because everything derives from Object. If you have some other, new method, the code using your instances will not know to call that method instead. It's the Liskov Substitution Principle at work.
What I say is why override it when i can implement my own new method in my defined type?
Because that is how the language feature has been designed, as you know every type in C# is inheriting from Object and Object defines the methods with default implementation to check equality of two objects, and we as developers creating new types might want to modify the behavior how equals method compare two objects of specific type.
Here is an example to understand why it is virtual:
int i = 1;
int j = 1;
Object o = i;
o.Equals(j); // now what will happen here if you have'nt overriden it
the int type contains the overriden implementation of Equals method which checks the two integers for equality, so when we will call Equals method using reference of type Object it will call the implementation defined in the type System.Int32,and we had a new method defined in the System.Int32 and not override the Equals method of Object, then we would see unexpected behavior as Object type implementation would have checked the memory addresses i.e reference equality.
Consider this example as well:
public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
}
public Person(string name)
{
_name = name;
}
public override string ToString()
{
return _name;
}
}
What if i want Equals method to not compare them by reference but instead we want to compare them on basis of name, in that case we would need to override the Equals method so that calling it either with Object type reference or Person type reference it would return the same result i.e not checking reference equality but checking the Name of two Person class objects.

How to detect current type has "ToString" overrided method or not? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to determine if the MethodInfo is an override of the base method
Normally, when we execute "ToString" method of any complex type it will return current type name like the following string except there is "ToString" overrided method.
System.Data.Entity.DynamicProxies.UserRole_D77A004638495805D68478322DF47F48540438D82DC9A5A0E1B0B2A181E4A100
I want some logic to detect current type about this because I try to export data to excel format. But some property of model is complex type that doesn't define "ToString" method. Output of this property is useless for normal user.
Thanks,
You can check the DeclaringType on the methodInfo of to string
if (methodInfo.DeclaringType != typeof(YourObject)) {
...
}
system.reflection.methodinfo
You can of course do this with reflection. An alternative approach that might give you what you want and doesn't use reflection is:
if (this.ToString() != this.GetType().ToString())
{
// This Type or one of its base types has overridden object.ToString()
}
Note that you probably want to check if the current type or any base type (except object) has overridden ToString(). As a contrived example all types derived from Exception return a sensible value from ToString() (exception details including stack trace), but not all override Exception.ToString().
I think this approach to check whether particular type overrides ToString or not is a little bit brittle. We can solve this in several other ways.
First of all if string representation is required you can add additional mixin interface like IObjectDescriptor with one method: string GetDescription. And you can require this implentation from every type (and if class is not implements it throw an exception).
Second approach (if we don't want to change existing code base) is use separate helper class that will have one method: ConvertToString:
static class ToStringHelper
{
// We can use Generic method to prevent boxing
public string ConvertToString(object o)
{
var sb = new StringBuilder();
// using reflection to access all public properties, for example
return sb.ToString();
}
}
In both cases your intention and "contract" between you and your clients would be much more clear. In first case you'll throw an exception if type is not implements particular interface, with second approach you'll get at least consistent behavior.
You can use IsSubclassOf object and DeclaringType of method.
public class BaseClass
{
public string Name;
public virtual void Write(string val)
{
}
}
public class SubClass : BaseClass
{
public string Address;
public override void Write(string val)
{
base.Write(val);
}
}
Test code:
Type objType = obj.GetType();
MethodInfo info = objType.GetMethod("Write");
if (objType.IsSubclassOf(info.DeclaringType))
{
Console.WriteLine("Not Override");
}
else
Console.WriteLine("Override");

Is "where T : class" not enforced in any way at compile time or run time?

In the following code, I pass a struct into a constructor that is expecting a class. Why does this compile and run without error (and produce the desired output)?
class Program
{
static void Main()
{
var entity = new Foo { Id = 3 };
var t = new Test<IEntity>(entity); // why doesn't this fail?
Console.WriteLine(t.Entity.Id.ToString());
Console.ReadKey();
}
}
public class Test<TEntity> where TEntity : class
{
public TEntity Entity { get; set; }
public Test(TEntity entity)
{
Entity = entity;
}
public void ClearEntity()
{
Entity = null;
}
}
public struct Foo : IEntity
{
public int Id { get; set; }
}
public interface IEntity
{
int Id { get; set; }
}
If I change my Main() method so that it includes a call to ClearEntity(), as shown below, it still generates no error. Why?
static void Main()
{
var entity = new Foo { Id = 3 };
var t = new Test<IEntity>(entity);
Console.WriteLine(t.Entity.Id.ToString());
t.ClearEntity(); // why doesn't this fail?
Console.ReadKey();
}
where TEntity : class forces TEntity to be a reference type, but an interface such as IEntity is a reference type.
See here:
http://msdn.microsoft.com/en-us/library/d5x73970(v=vs.80).aspx
where T : class | The type argument must be a reference type, including any class, interface, delegate, or array type
Regarding your second question, you might think t.ClearEntity() would fail because it's assigning null to a variable whose type is a value type, but that's not the case. The compile-time type of Entity is the reference type IEntity, and the runtime type (after assignment) is the null type. So you never have a variable of type Foo but value null.
from the C# documentation:
where T : class
The type argument must be a reference type, including any class, interface, delegate, or array type. (See note below.)
Because you're passing the struct via an interface, it's still considered a reference type.
Within the .net runtime, every non-nullable value type has an associated reference type (often referred to as a "boxed value type") which derives from System.ValueType. Saying Object Foo = 5; won't actually store an Int32 into Foo; instead it will create a new instance of the reference type associated with Int32 and store a reference to that instance. A class constraint on a generic type specifies that the type in question must be some sort of a reference type, but does not by itself exclude the possibility that the type may be used to pass a reference to a boxed value-type instance. In most contexts outside generic type constraints, interface types are regarded as class types.
It's important to note that not only are boxed value types stored like reference types; they behave like reference types. For example, List<string>.Enumerator is a value type which implements IEnumerator<string>. If one has two variables of type List<string>.Enumerator, copying one to the other will copy the state of the enumeration, such that there will be two separate and independent enumerators which point to the same list. Copying one of those variables to a variable of type IEnumerator<string> will create a new instance of the boxed value type associated with List<string.Enumerator and store in the latter variable a reference to that new object (which will be a third independent enumerator). Copying that variable to another of type IEnumerator<string>, however, will simply store a reference to the existing object (since IEnumerator<string> is a reference type).
The C# language tries to pretend that value types derive from Object, but within the guts of the .net Runtime they really don't. Instead, they're convertible to types which derive from System.ValueType (which in turn derives from Object). The latter types will satisfy a type constraint, even though the former ones will not. Incidentally, despite its name, System.ValueType is actually a class type.
I, likewise, assumed that constraint keyword class meant the same class as the type declaration keyword class, but it doesn't.
As explained in the other answers, the term class here is over-loaded, which seems to me to be a horrible decision for the C# language design. Something like referencetype would have been more helpful.

Most efficient way to check if an object is a value type

WARNING: THIS CODE SUCKS, SEE ANTHONY'S COMMENTS
Which is faster?
1.
public bool IsValueType<T>(T obj){
return obj is ValueType;
}
2.
public bool IsValueType<T>(T obj){
return obj == null ? false : obj.GetType().IsValueType;
}
3.
public bool IsValueType<T>(T obj){
return default(T) != null;
}
4.Something else
You aren't really testing an object - you want to test the type. To call those, the caller must know the type, but... meh. Given a signature <T>(T obj) the only sane answer is:
public bool IsValueType<T>() {
return typeof(T).IsValueType;
}
or if we want to use an example object for type inference purposes:
public bool IsValueType<T>(T obj) {
return typeof(T).IsValueType;
}
this doesn't need boxing (GetType() is boxing), and doesn't have problems with Nullable<T>. A more interesting case is when you are passing object...
public bool IsValueType(object obj);
here, we already have massive problems with null, since that could be an empty Nullable<T> (a struct) or a class. But A reasonable attempt would be:
public bool IsValueType(object obj) {
return obj != null && obj.GetType().IsValueType;
}
but note that it is incorrect (and unfixable) for empty Nullable<T>s. Here it becomes pointless to worry about boxing as we are already boxed.
My first answer would be to write a simple test and find out for yourself.
My second answer (without any testing on my part, of course) would be option 1. It is the simplest check. The second method involves two separate checks while the third involves creating a default instance of a type.
You should also consider readability. The framework already gives you the ability to have the following in your code:
if(someObj is ValueType)
{
// Do some work
}
Why even bother creating a method that would simply turn the above statement into (assuming you made your method static and allowed the compiler to infer the generic type):
if(IsValueType(someObj))
{
// Do some work
}
Defining a struct actually defines two types: a value type, and a class type which derives from System.ValueType. If a request is made to create a variable, parameter, field, or array (collectively, 'storage location') of a type which derives from System.ValueType, the system will instead create a storage location which will store the object's fields rather than storing a reference to an object in which those fields appear. On the other hand, if a request is made to create an instance of a type deriving from System.ValueType, the system will create an object instance of a class which derives from System.ValueType.
This may be demonstrated by creating a struct which implements IValue:
interface IValue {int value {get; set;}};
struct ValueStruct : IValue
{
public int value {get; set;}};
}
with generic test routine and code to wrap it:
static void Test<T>(T it) where T:IValue
{
T duplicate = it;
it.value += 1;
duplicate.value += 10;
Console.WriteLine(it.value.ToString());
}
static void Test()
{
ValueStruct v1 = new ValueStruct();
v1.value = 9;
IValue v2 = v1;
Test<ValueStruct>(v1);
Test<ValueStruct>(v1);
Test<IValue>(v1);
Test<IValue>(v1);
Test<IValue>(v2);
Test<IValue>(v2);
}
Note that in every case, calling GetType on the parameter passed to Test would yield ValueStruct, which will report itself as a value type. Nonetheless, the passed-in item will only be a "real" value type on the first two calls. On the third and fourth calls, it will really be a class type, as demonstrated by the fact that a change to duplicate will affect it. And on the fifth and sixth calls, the change will be propagated back to v2, so the second call will "see" it.
static class Metadata<T>
{
static public readonly Type Type = typeof(T);
static public readonly bool IsValueType = Metadata<T>.Type.IsValueType;
}
//fast test if T is ValueType
if(Metadata<T>.IsValueType) //only read static readonly field!
{
//...
}
There are two rules:
1-All Classes are reference types such as Object and String, so it's supported by .NET Framework classes.
2-All structures are value types such as bool and char, even though it contain reference member, so it's supported by .NET Framework structures.
Simply right click on any type and Go To Definition if it's a Class so that means it a reference type else if it's a Struct so that means it's a value type :)
You can use
obj.GetType().IsValueType
This uses reflection but clear way instead of care of boxing unboxing.

Categories

Resources