Why i can't access protected property in the derived class - c#

I have a two classes.This is my code:
//My Base class
public class People
{
public People()
{
}
protected string name;
protected string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
}
//The Child class
public class Student:People
{
private int id;
public Student()
{
}
public Student (int id, string name)
{
this.id = id;
this.Name = name;
}
public int ID
{
get
{
return this.id;
}
set
{
this.id = value;
}
}
}
When i create instance of the Student class like the one below i can't access the NAME property from the parent class People.
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
Student student1 = new Student();
student1. // only ID property is accessible
}
}
Do i make something wrong? Since Students is child class of People i expected that the NAME property should be accessible trough the Student instances.Thank you very much for the help in advance.

You're not doing anything wrong, but if you want to access
Name
via an instance of
Student
You have to declare that property public. Otherwise, only access from within that class is allowed (not via an instance).

You are still accessing it Outside the class so it would need to be public.
You can read about access modifiers here:
http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx
Change your properties to:
public string Name {get;set;}
And you should be good to go.

The Student class does not expose the Name property to the outside.
If you would derive a class from student, you could access the Name property.
Alternatively, you could reimplement Name using the new keyword like this:
public class Student : People
{
private int id;
public new String Name { get; set;}
public Student()
{
}
public Student(int id, string name)
{
this.id = id;
this.Name = name;
}
public int ID
{
get
{
return this.id;
}
set
{
this.id = value;
}
}
}

you should make your Properties public
//My Base class
public class People
{
public People()
{
}
protected string name;
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
}

You can not access protected property of base class using instance of a derived class.
Protected property if a property that can be accessed only within bounds of derived types.
If you need to access to that property from instance of the Student, declare it like a public inside its base class: People.
If you also need in some way override its behavior, can declare it public virtual in base class and override it in Student

I believe your problem is that your protected fields are in the base class not the inherited class. Look at this: http://msdn.microsoft.com/en-us/library/bcd5672a.aspx
public class BaseClass
{
public string foo
}
public class SubClass
{
protected string bar
}
This is a more common use of protected.

Related

Getter not working on returning Object to String

Trying to call the getName() method within my program to write back to a file from a Windows Form. Name is another object called public class Name() with its own sets/gets that i can implement fine but i cannot figure out how to set my getName() to be able to call back the gets from the Student Object.
public class Student
{
private Name n;
private Address a;
private PhoneNumber[] phones = new PhoneNumber[3];
private Course[] c = new Course[200];
public void setName(Name N)
{
n = N;
}
public string getName()
{
return n;
}
}
Name is a class, not a string.
Either you do
public string getName()
{
//Assuming name is a string property in your Name class
return n.Name;
}
As sais above this assumes your Name class is made up like
class Name
{
public string Name {get; set;}
}
or you override the .ToString() method in the Name class to return the name property.
Overriding .ToString() is explained in MSDN

Default value of fields in derived classes

Is there a way i can have derived classes override the default value of the base class? In the example below i would need the Hammer.Name to return "Hammer".
public class ItemBase
{
public string Name = "Base";
}
public class Hammer: ItemBase
{
new public string Name = "Hammer";
}
public class Test
{
ItemBase MyThing = new Hammer();
// Prints "Base"
Console.WriteLine(ItemBase.Name);
}
You don't need different fields, you need different initializations of the same field.
class Base {
protected string name = "";
public Base() { name = "X"};
}
class Derived : Base {
public Derived() { name = "Y"}; //same {name } field of a Base class
}
You might consider using virtual properties instead of exposing public fields (which is considered bad practice).
As such, you can (with C# 6.0):
void Main()
{
ItemBase myThing = new Hammer();
// Doesn't print "Base"
Console.WriteLine(myThing.Name);
}
public class ItemBase
{
public virtual string Name { get; } = "Base";
}
public class Hammer : ItemBase
{
public override string Name { get; } = "Hammer";
}
or (if you're using older version of C#)...
public class ItemBase
{
public virtual string Name { get { return "Base"; } }
}
public class Hammer : ItemBase
{
public override string Name { get { return "Hammer"; } }
}
You are not defining a new default value in the derived type, you are declaring a completely new field that hides the field with the same name in the base class.
Because fields can't be virtual, the returned field is the one declared in the type through which you are invoking it.
Solution? Don't redeclare a new field, simply assign a new value to the existing field in the constructor of the derived type:
public class Hammer
{
public Hammer() {
Name = "Hammer"; }
}
Trying to figure out what exactly is needed while skating around the .NET version restrictions has been a headache but I have a solution. According to your comments you can use a constructor.
In that case this is really easy to do with properties (which are the preferred way to handle your situation) instead of public fields:
public class ItemBase
{
public ItemBase()
{
//When instantiating ItemBase the value of Name is "Base"
Name = "Base";
}
public string Name { get; set; }
}
public class Hammer : ItemBase
{
public Hammer()
{
//When instantiating Hammer the value of Name is "Hammer"
Name = "Hammer";
}
}
And to test just run this:
public class Program
{
public static void Main()
{
ItemBase itemBase = new Hammer();
Console.WriteLine(itemBase.Name);
itemBase.Name = "Foo";
Console.WriteLine(itemBase.Name);
}
}
Outputs:
Hammer
Foo
This should check off all the boxes. You now use properties (making your code better), each class has a default value, and the properties can be changed after instantiation.

is it possible to set derived class default values without a constructor?

My goal is to make a static object that won't change, using a base class's member variables and abstract methods, as there will be multiple of these type of objects.
This is an example of what I want to do:
public abstract class BaseThing
{
public string Name { get; set; }
public string Description { get; set; }
public decimal Cost { get; set;}
public abstract void MethodThatDoesThings();
}
Then I want to have a derived object that has default values of those base variables, something like this (obviously doesn't work) :
public class DerivedThing : BaseThing
{
Name = "Name1";
Description = "Description1";
Cost = 1.00;
public override void MethodThatDoesThings()
{
//Actually does things
}
}
Is something like this possible without using a constructor? Not that I'm against using them, I'm just genuinely curious. Right now I feel as though my only option is to create many static classes that have the same properties.
No, you should implement a constructor for derived class to set default values. If you want to set default values, you can do it like this;
public class DerivedThing : BaseThing
{
public DerivedThing(string name = "Name", string description = "Description1", decimal cost = 1.0)
{
Name = name;
Description = description;
Cost = cost;
}
public override void MethodThatDoesThings()
{
}
}

Set a read only property defined in a interface within a concrete class

I have an interface with a read only property
public interface IPerson
{
string Name { get; }
}
and a concrete class...
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name
{
get
{
return Name;
}
}
}
I want Name to be read only externally to this class, but how do I set it from within the concrete class?
Error: Person.Name cannot be assigned to.
How do I set the value of this property from within Person class?
This doesn't have anything to do with the interface, you're just declaring the property incorrectly. In C# 6, you can create a read-only property like this:
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; }
}
In earlier versions, you can use a read-only backing field which you can set:
public class Person : IPerson
{
private readonly string _name;
public Person()
{
_name = "Person";
}
public string Name
{
get { return _name; }
}
}
Note that the interface only requires the property has a getter, the implementation doesn't have to be read-only. You could add a setter if you had reason to modify the value:
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; set; }
}
The setter could be private if you only needed to be able to change the value from within the class.
You can use a private property to hold the value.
public class Person : IPerson
{
private string _name;
public Person()
{
_name = "Person";
}
public string Name
{
get
{
return _name;
}
}
}
Right now, you're trying to read the property by reading the property. Needless to say, this will result in an endless loop. Instead, you either need to use full-blown auto-properties, or a manual backing field.
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; private set; }
}
You simply have a private setter (pre c#6):
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; private set; }
}
Try using accessors:
private string _name;
public string Name
{
get
{
return _name;
}
}
You can then set the value of _name inside any method or the constructor.
I want Name to be read only externally to this class, but how do I set it from within the concrete class
First of all, let's realize that: an interface only describes a set of public requirements; it does not prevent us from implementing other public members, nor does it limit our ability to create private members.
Therefore, to make a property writeable from inside the class but read-only elsewhere, we can declare the set method with private scope:
public class Person : IPerson
{
// Name is read-only outside the class, but can be set internally
public string Name { get; private set; } = "DefaultName";
public Person() { }
public Person(string name)
{
// Potentially do some validation before setting the name
if (!IsValidName(name))
throw new ArgumentException("Name cannot be null, empty, or whitespace.");
Name = name;
}
private bool IsValidName(string name)
{
return !string.IsNullOrWhitespace(name);
}
// Continued below...
And if we want to, we can give access to the private setter through a method. This is often done in order to make the renaming of a person very intentional (for example, it prevents accidental assignments when a comparison was intended). The client will get a design-time error from the compiler if they try person.Name = "Foo"; but they can write person.RenameAs("Foo");
public void RenameAs(string newName)
{
// Potentially do some validation before setting the name
if (IsValidName(newName)) Name = newName;
}
}

UML mapping with c#

There are two classes Person and Employee
when it mapped to c# code
public class Person
{
private string Name;
}
public class Employee : Person
{
private string Department;
public string GetName()
{
return "Person Name";
}
}
My question is where can i write the getters and setters for this private attributes.is it ok to write them with in the same Person and Employee classes if yes isn't there a problem with mapping? because methods are also with in the same class(GetName()) or do i have to use separate classes for writing getters and setters.i'm confused with this class diagram mapping with the code.Can any one resolve this for me??
Firstly, I would recommend you to you the properties approach and not the getters / setters one.
My take:
public class Person {
private string name;
public string Name {
get {
return this.name;
}
}
}
public class Department {
private int id;
private string name;
public int ID {
get {
return this.id;
}
}
public string Name {
get {
return this.name;
}
}
}
public class Employee : Person {
private Department department;
public Department Department {
get {
return this.department;
}
}
}
Employee.Name returns the employee name which is being declared within the Person class.

Categories