Click here to Skip to main content
15,893,266 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hello,

I have a statement:
Class1 c = new Object(); ////this will cause an error this is because Class1 is object's derived type so i will have to do:

Class1 c = (Class1) new Object();

But if i do :

Object o = new Class1();/// this works

Well, the first statement wont work, because it is not allowed by CLR. Why is that so?


Thanks
Posted
Updated 28-Dec-13 23:31pm
v3
Comments
Sergey Alexandrovich Kryukov 22-Dec-13 13:25pm    
How about reading of some language, .NET and OOP manual? The question is very elementary, and it makes things especially difficult to explain.
—SA

This is not even real OOP, this is the very basics of programming: inheritance.

Imaging that the assignment is possible:
C#
class MyClass {
   internal int Field;
}

MyClass instance = new object(); // imagine for a second that this is possible
// but then, this would be possible:
instance.Field = 2; // addressing not existing member

Here, runtime type of instance is actually System.Object, so this object does not have the field Field. But the assignment in question would create a variable of the compile-time type of MyClass, giving the access to this field, which really does not exist in memory.

The assignment a variable of more derived to a variable of a base class is always possible though. I hope it's clear why.

—SA
 
Share this answer
 
Comments
Rahul VB 22-Dec-13 14:59pm    
Respected Sir,
Thanks a lot for your post, very helpful. I understand that my doubt is sounding very elementary or basic. But i am just a beginner i needed a short briefing on this topic.thanks for that.

Thanks a lot
Sergey Alexandrovich Kryukov 22-Dec-13 15:08pm    
There is nothing wrong with that. My advice on "elementary" is only to take a manual and read it with full understanding step-by-step, doing some simple exercises. Try not to jump over basic topics; what is most elementary is at the same time the most fundamental.
You are welcome.
Good luck,
—SA
Rahul VB 23-Dec-13 14:59pm    
Respected Sir,
Thanks for help. I will have to dig deep into object oriented concepts, my every application has a bug.....haha. Sometimes it becomes difficult to simulate a situation like this:
Class1.Field = 1;
OR
Class1 c = new Class1();
c.Field = 1;
- I understand that the above field can either be static or an instance field. So both statements at once wont be possible(I hope i am correct).
- Or a situation :
Class1 : Class2
{
//// here i can use a field of Class2 directly as i have derived from Class2.
//// Or rather if that field is an instance field then i will use an object of Class2 to access that field if i have not inherited or may be inherited from Class2.
//// I just want to track down a difference between the above statements during runtime.

}





thanks a lot,
Rahul
Sergey Alexandrovich Kryukov 23-Dec-13 15:25pm    
Now, you are touching another issue, static fields vs. non-static ones (instance fields). This is a separate topic. I can give you the idea, please wait.
—SA
Sergey Alexandrovich Kryukov 23-Dec-13 15:42pm    
It really deserves a separate answer, so I put one. Please see Solution 3.
—SA
It may be helpful to think that 'Object is kind of the "root" of most of the constructs/objects in .NET: including Value Types, such as Integer, and Reference Types such as Classes, Collections, etc.

Interfaces and (unsafe code) Pointer Types, and generic "open" parameter Types, do not inherit from Object.

Eric Lippert eloquently analyzes this in his essay, "Not everything derives from object:" [^].

We are frequently dealing with objects in .NET that have complex levels of inheritance; consider a WinForms Button:

System.Object
 System.MarshalByRefObject
  System.ComponentModel.Component
   System.Windows.Forms.Control
    System.Windows.Forms.ButtonBase
     System.Windows.For System.Windows.Forms.Button

You can think of each of the "ancestors" of Button as exposing facilities that can be accessed by any instance of Button, such as Methods, Fields, etc.

It makes sense to say: "a Button is a child of all its ancestors," just as makes it sense to say that you are a child of your ancestors.

It doesn't make sense to say your grandfather is a child of you, and it doesn't make sense to say that a System.Windows.Forms.ButtonBase is a child of a Button.

So, there's a one-way arrow in an object's inheritance tree.

It's logical that I can take any instance of a Button, and deal with it as any of its object ancestors: you can think of this as down-casting, and while the object down-cast may cease to expose the unique facilities provided by its higher-level Type, it doesn't cease to be an instance of the higher-level Type.

An example may help illustrate this: every .NET Control exposes a 'Tag field into which any object can be placed.

Let's assume you have a WinForm Project, and an instance of a TreeView, 'treeView1, placed on 'Form1. At design time you add some root Nodes to the TreeView.

If you add a Class, like this:
C#
public class TreeNodeTag
{
    public int ID { get; set; }
    public string Comments { get; set; }

    public TreeNodeTag(int id, string comments)
    {
        ID = id;
        Comments = comments;
    }
}
To your project, and then define some variables, and an EventHandler for the Form Load Event like this:
private TreeNode currentNode;
private TreeNodeTag currentNodeTag;

private void Form1_Load(object sender, EventArgs e)
{
    // the TreeView must have Nodes created in it
    // for this to work without error, and this code
    // creates Tags for only the root-level TreeNodes
    for (int i = 0; i < treeView1.Nodes.Count; i++)
    {
        currentNode = treeView1.Nodes[i];
        currentNodeTag = new TreeNodeTag(i, "comment " + i.ToString());
        currentNode.Tag = currentNodeTag;
    }
}
Now, every root-level TreeNode has an instance of a 'TreeNodeTag in its 'Tag Property, but this instance is down-cast into Type Object.

So, what if you want to access the TreeNodeTag as TreeNodeTag, not as Object: for example, assume you've defined an 'AfterSelect EventHandler for the TreeView:
C#
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    currentNode = e.Node;
    currentNodeTag = currentNode.Tag as TreeNodeTag;

    // check to make sure we have a TreeNodeTag Type Tag object
    if(currentNodeTag == null)
    {
        MessageBox.Show(string.Format("Node: {0} does not have a Custom Tag Object", currentNode.Text));
        return;
    }

    MessageBox.Show(string.Format("Node: {0} ID: {1} Comments: {2}", currentNode.Text, currentNodeTag.ID.ToString(), currentNodeTag.Comments));
}
As you can see in this code, an instance of the TreeNodeTag Class is stored in the Tag Property of the TreeView's Nodes as Type 'Object, but it is not "stripped" of its information.

When we retrieve the TreeNode.Tag, we can cast it back to its higher-level Type, and, all the information stored in it is accessible.

While this may seem to "violate" the idea of the one-way nature of object inheritance, it really means that the information in a higher-level object can be restricted from use, or view by down-casting it to an ancestral form.

Hope this meandering essay is useful :) If not, I'll remove it.
 
Share this answer
 
v3
Comments
Rahul VB 22-Dec-13 14:59pm    
Respected sir,
Thanks a lot for explaining so nicely. I keep reading theories, but it is good to hear from professionals especially in the form of code snippets. You made the picture more clear.

Thanks a lot
In response to the follow-up question posed as a follow-up question in the comments to Solution 1:

You need also to learn static members vs instance (non-static) members. First of all, please read my past answers:
What makes static methods accessible?[^],
C# windows base this key word related and its uses in the application[^].

To illustrate just the instance fields, let's do this:
C#
class MyClass {
   internal static int SomeStaticField;
   internal string SomeInstanceField;
   // before we show usage from outside of the class:
   static void SetStaticField(int value) {  // could also be non-static, be static is enough
       SomeStaticField = value; // "this." cannot be used, as if would refer the instance
       // or even
       MyClass.SomeStaticField = value;
   } 
   void SetInstanceField(string value) {
       this.SomeInstanceField = value; // and "this." can be omitted
   }
   // of course, in real software we should use properties,
   // but this was only to get into the essence of things
}

//...
// usage:

MyClass instanceOne = new MyClass();
MyClass instanceTwo = new MyClass();

instanceOne.SomeInstanceField = "first";
instanceTwo.SomeInstanceField = "second";

// now, two different instance have different values of SomeInstanceField

// but:
MyClass.SomeStaticField = 13; // is the same for all instances, this is the value per class, not per each instance

// also, you can call
MyClass.SetStaticField(14);

// or
instanceOne.SetInstaceField("some other value"); // and not visa versa, please see below


Additionally you should understand instance methods vs static methods. Static methods have no access to the instance, so they can only call access other static members of the same class or structure. How non-static method can have this access? They have additional implicit (not explicitly written parameter denoted as "this"), which is the reference to the instance on which you call the method (see above: such as instanceOne).

The prefix "this." can usually be omitted, but sometimes it is needed to resolve the ambiguity, because you can also have a local variable or a parameter named exactly as the field. This is allowed but requires the resolution using "this."; in practice this clash most usually happens with constructor parameters.

—SA
 
Share this answer
 
v6
Comments
Rahul VB 24-Dec-13 3:39am    
Respected Sir,
Very nice thanks a lot.

Rahul
Sergey Alexandrovich Kryukov 24-Dec-13 3:41am    
You are very welcome.
Good luck, call again.
Happy learning.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900