Hi everyone. I'm currently working on a project with c#, and had some questions about classes. I'm a python programmer, so bear with me ;) How would I make a class that has pre defined arguments? I.e. even if the user doesn't pass that arguement, the default value of it will take over. Here's an example in python (hopefully it will make some sense):

class A():
   # constructor
   def __init__(self,name,age,height='5 feet'):
      self.name = name
      self.age = age
      self.height = height
   def say(self):
      print(self.height)


>>> inst = A('Luke',61)
>>> inst.say()
>>> '5 feet'
>>>
>>>
>>> inst2 = A('Mark',45,'6 feet, 3 inches')
>>> inst2.say()
>>> '6 feet, 3 inches'

So in this case, the variable height is already declared, even if the user doesn't specifiy it. How would I go about doing this in c#? I can't really think of a solution. Thanks!

actually line 16 in the code should be

>>> inst2 = A('Mark',45,height='6 feet, 3 inches')

I don't know that much of Python(Monty you know) but I'm going to make an effort at a translation here that fits your code as close as possible:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A inst = new A("Luke",61);
            inst.say();
            A inst2 = new A("Mark", 45, "6 feet, 3 inches");
            inst2.say();

            Console.ReadKey(); //keep console on screen
        }       
    }

    public class A
    {
        private string name = string.Empty;
        private int age = 0;
        private string height = string.Empty; 

        //constructors
        public A(string Name, int Age)
        {
            this.name = Name;
            this.age = Age;
            this.height = "5 feet";
        }

        public A(string Name, int Age, string Heigth)
        {
            this.name = Name;
            this.age = Age;
            this.height = Heigth;
        }

        public void say()
        {
            Console.WriteLine(this.height);
        }
    }
}

I hope this makes some things clear.

Comments
great answer

oh ok. Thats kind of cheating since you have 2 constructors :) I have 4 more questions if you want to answer them ;)
- so in c# is 'this' the same as 'self' in python? 'self' meaning that the next period and variable/function are part of the class?
- Also, in a c# class, should I make all variables and funcions private so that no other piece of code can access it?
- when creating an instance of a class,do I need to put 'new' after the equal sign? Why can't i just right A('luke',10)?
- do I need a deconstructor

thanks so much!

Why do you call that cheating?
It is called the signature of a method.
I can have 100 constructors if I want to. I don't need to have destructors or deconstuctors as you call them. C# takes care of that.
I used this to say what you said and to make it clearer to a reader of my code, I did not have to do that.
I made the fields(variables) of my class private because I don't see why anyone else would need them. If you don't want that behaviour, just use the word public.

Edited 6 Years Ago by ddanbe: n/a

thanks! btw i call it cheating because in python you can only call the constructor (in python its def __init__()) once :p

>> - so in c# is 'this' the same as 'self' in python? 'self' meaning that the next period and variable/function are part of the class?

Yes. When you're dealing with derived classes "this.<name>" could also point to a member in the base class if you did not override it in the current class, or hide it with the new operator. This gets pretty tricky and is probably more of an answer than you were looking for but you can use this and base .

You can find more information about inheritence, overriding, and hiding in this thread:
http://www.daniweb.com/forums/thread204913.html

>> - Also, in a c# class, should I make all variables and funcions private so that no other piece of code can access it?

The "best practices" for C# dictate that you not expose fields publicy.
Bad:

public string FirstName;

The code Danny posted was following those best practices there just weren't any public properties defined to access the private fields because, well, you didn't ask about that in your original question so he probably didn't include them since you didn't ask :P

To expand on danny's example:

public class A
  {
    //Fields
    private string _name;
    private int _age;
    private string _height;
    //Properties
    public string Name
    {
      get { return _name; }
      set { _name = value; }
    }
    public int Age
    {
      get { return _age; }
      set { _age = value; }
    }
    public string Height
    {
      get { return _height; }
      set { _height = value; }
    }
    //Constructors
    public A()
    {
    }
    public A(string Name)
      : this()
    {
      this.Name = Name;
    }
    public A(string Name, int Age)
      : this(Name)
    {
      this.Age = Age;
    }
    public A(string Name, int Age, string Height)
      : this(Name, Age)
    {
      this.Height = Height;
    }
    //Methods
    public void Say()
    {
      Console.WriteLine("...");
    }
  }

I renamed the members but this is strictly preference. I prefix private fields with underscores, but some people use "m" or a letter signifying the data type. I also prefer to chain my constructors but some people don't because it doesn't give you as much flexibility when designing the class. It is all up to you.

>> - when creating an instance of a class,do I need to put 'new' after the equal sign? Why can't i just right A('luke',10)?

Yes. It is part of the language specification so I don't really have a good answer beyond that you need to do it. I'm sure there is an article detailing somewhere how it distinguishes creating a new reference to an instance of the class versus reference the type.

>> - do I need a deconstructor
Yes. If you don't define a constructor then the compiler will automatically generate a parameterless constructor for. Take this for example:

public class B
  {
    public string Name { get; set; }
    public string Height { get; set; }
  }

You can create an instance of that class with:

B b = new B();
        b.Name = "";

The parameterless constructor is sort of a magic constructor in some cases. When you use the XmlSerializer to serialize/deserialize classes it uses reflection to create an instance of the class and it calls the parameterless constructor. If you mark your parameterless constructor as private or have it throw an exception then you cannot use XmlSerializer to serialize your class. These are decisions you need to have in mind when designing classes. In some cases, and I do this, you do not want someone to create an instance of your class. For example I have a class that parses a response from a merchant gateway for online payments and it holds all of the data from the response. There will never be a reason for anyone to instantiate a class without having a valid response string from the merchant so I designed the class like this:

public class TxResponse
  {
    public decimal TransactionAmount { get; set; }
    public bool Approved { get; set; }
    //Private ctor, you cannot call it outside of this class
    private TxResponse()
    {
    }
    public static TxResponse ParseResponse(string s)
    {
      if (!IsValidResponseString(s))
        return null;
      else
      {
        TxResponse result = new TxResponse();
        result.Approved = true;
        result.TransactionAmount = 50M;
        return result;
      }

    }
    private static bool IsValidResponseString(string s)
    {
      return !string.IsNullOrEmpty(s); //This would actually be code to parse the response
    }
  }

For this class you can't use the new operator to instantiate a new instance since the constructor is private. By design I forced that an instance be created by calling a static method of the class.
You can also see this design in the .NET framework -- the Graphics class has no constructors defined, but you use that class in every winform application. You have to create new instances through static methods or from controls. supporting .CreateGraphics() .


[edit]
I just noticed your question said deconstructor and not constructor. In C# you should implement IDisposable to clean up any managed resources you have instantiated in your class, and use a ~Finalizer to clean up any unmanaged resources like file handles.
[/edit]

Edited 6 Years Ago by happygeek: spelling error corrected on request

Comments
The great expander!!! Thanks for the reminder on IDisposable!

Be sure to post back with your progress :)

Please mark this thread as solved if you have found an answer to your question and good luck!

This question has already been answered. Start a new discussion instead.