How to Protect Base Field's Public/Private - c#

If i have a ClassA
public class ClassA
{
public string name;
}
Where Attribute Name is Public ,and it can be modified from Anywhere .
Than i have a ClassB
public class ClassB : ClassA
{
private string name;//But it's not Woking ,name is still public
}
...which Inherit's ClassA ,but i need at ClassB to make name as Private Field.
So if i create an Object of Type ClassB than ClassB.name cannot be modified .

just don't publish the field but accessors:
public class ClassA
{
private string _name;
public string Name { get { return _name; } protected set { _name = value; } }
}
public class ClassB : ClassA
{
/* nothing left to do - you can set Name in here but not from outside */
}

This is not possible. You can not change visibility of base class's field.

Assuming you cannot change A, do not use inheritance, but aggregation and delegation:
public class A {
public string name;
public int f() { return 42; }
}
public class B {
private A a;
public int f() { return a.f(); }
public string getName() { return a.name; }
}

Carsten Konig's method is a good way, and here is an alternative.
public class ClassA {
public virtual string Name {
get;
private set;
}
}
public class ClassB : ClassA {
public override string Name {
get {
return base.Name;
}
}
}

Hm. There is a pair of tricks for this. But none of them is what you really want. One is:
public class ClassA
{
protected string name;
public string Name { get { return name; } public set { name = value; } }
}
public class ClassB : ClassA
{
public new string Name { get { return base.name; } }
}

If you don't have control over ClassA, you can do this:
void Main()
{
var b = new ClassB();
var a = (ClassA)b;
a.name = "hello";
b.PrintName();
}
class ClassA {
public string name;
}
class ClassB : ClassA {
private new string name;
public void PrintName() {
Console.WriteLine(base.name);
}
}

Related

Winforms DataGridView columns from datasource

I have base class and some inherited classes, like this:
public abstract class Base
{
public long ID { get; set; }
public string Name { get; set; }
public virtual string Description { get { return "Base"; } }
}
public class A : Base
{
public override string Description { get { return "A"; } }
}
public class B : Base
{
private string extraInfo;
public override string Description { get { return "B"; } }
public string ExtraInfo
{
get { return extraInfo; }
set { extraInfo = value; }
}
}
I have collection of these objects and I set this collection to DataSource of DataGridView. Then, columns of DataGridView will be created by Base class's properties (ID, Name. Description). Is there any way to reflect also concrete implementation properties?
List<Base> items = new List<Base>();
DataGridView dgv = new DataGridView();
dgv.DataSource = new BindingList<Base>(items);
In this case, I want also column for ExtraInfo property of class B.
Inherit class B too:
public class Base
{
public long ID { get; set; }
public string Name { get; set; }
public virtual string Description { get { return "Base"; } }
}
public class A : Base
{
public override string Description { get { return "A"; } }
}
public class B : Base
{
private string extraInfo;
public override string Description { get { return "B"; } }
public string ExtraInfo
{
get { return extraInfo; }
set { extraInfo = value; }
}
}

Access static constant of a subclass from the base class

I have an Animal base class and every subclass needs a static string ID for identification purposes.
So I might have:
public class Dog : Animal {
public static readonly string ID = "dog";
}
I do this because I frequently need to use Dog.ID throughout my app - in places where I don't yet have an instance.
However, I also need to access this when I have an instance, but I only want to put something like GetId() in the base class:
public class Animal {
public string GetId() {
return ID;
}
}
The problem is, Animal would not have access to the static ID field in the children.
Is there a way to do this that I've overlooked?
What about an abstract method?
public class Dog : Animal
{
public static readonly string ID = "dog";
public override string GetId()
{
return ID;
}
}
public abstract class Animal
{
public abstract string GetId();
}
or virtual
public class Animal
{
public virtual string GetId()
{
return null;
}
}
Ugly... But you could use reflection:
FieldInfo id = GetType().GetField("ID", BindingFlags.Public | BindingFlags.Static);
return id.GetValue(null);
If this is a static, set-once identifier, it seems like you should use an attribute instead of a static field or property:
public class AnimalIdAttribute : Attribute
{
public AnimalIdAttribute(string id)
{
Id = id;
}
public string Id { get; }
}
public class Animal
{
public string Id => this.GetCustomAttribute<AnimalIdAttribute>(true)?.Id;
}
[AnimalId("dog")]
public class Dog : Animal
{
}
Also, if any animal should provide an Id, your Animal class should be an abstract class which should also define an abstract Id property:
public abstract class Animal
{
// Now you can access Id property implementation
// from Animal
public abstract string Id { get; }
}
public class Dog : Animal
{
public override string Id { get; } = "dog";
}
Or, you can do something like this:
public class Animal
{
public static string Id;
public virtual string GetId()
{
return Id;
}
}
public class Dog : Animal
{
public new static readonly string Id = "dog";
public override string GetId()
{
return Id;
}
}
This gives you ability to call Id from Class or an instance.
Implement explicit interface like this
public class Animal : IType
{
private static string _ID = "Animal";
string IType.ID
{
get
{
return getID();
}
}
public virtual string getID()
{
return _ID;
}
}
public class Dog : Animal, IType
{
public static readonly string _dogID = "dog";
string IType.ID
{
get
{
return _dogID;
}
}
public override string getID()
{
return _dogID;
}
}
....
// usage
Animal a = new Animal();
Animal d = new Dog();
Console.WriteLine(a.getID());
Console.WriteLine(d.getID());
If you agree to an assumption that ID equals to the type name, you can use this approach. It lets you define and inherit ID property in the base class.
Though I agree this might look quite strange at first sight.
public class Animal<T> where T : Animal<T>
{
public static readonly string ID = typeof(T).Name;
}
public class Dog : Animal<Dog>
{
}
public class Cat : Animal<Cat>
{
}
Expression Cat.ID will return Cat, and Dog.ID will return Dog.

how would i set the value for this variable?

I have been given this interface to start with. There are a number of functions I must implement.
using System;
using System.Windows.Forms;
public interface IInfoCard
{
string Name { get; set; }
string Category { get; }
string GetDataAsString();
void DisplayData(Panel displayPanel);
void CloseDisplay();
bool EditData();
}
How would I implement the following function into the interface.
class Class2 : IInfoCard
{
public string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
You should use then Abstract classes, not interfaces, then.
public abstract class IInfoCard
{
string Name { get; set; }
string Category { get; }
string GetDataAsString() { return null; }
void DisplayData(Panel displayPanel) {}
void CloseDisplay() {}
bool EditData() { return true;}
}
You are trying to implement a property. You can basically encapsulate a field.
An easy way to do that is using auto-property:
public string Name { get; set; }
Try this
public class Class2 : IInfoCard
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
}
You can use Auto-Implemented Properties
public class Class2 : IInfoCard
{
public string Name { get; set;}
}
See More
You have two options.
Option 1:
Make them Auto properties, in which case compiler creates a private, anonymous backing field.
public string Name {get;set};
Option 2
Defining an explicit backing field, a private field.
private string name;
public string Name
{
get { return name; }
set { name = value; }
}

C# unknown type property

I have a class like this:
public class Student
{
private string NumberP;
public string Number
{
get{return NumberP;}
set{NumberP=value;}
}
}
public class School
{
private string NameP;
public string Name
{
get{return NameP;}
set{NameP=value;}
}
}
I want to declare a Type from another class like (school or Student), but I don't know its type.
How Can I declare a property unknown type. I will set unknown type another time
public class MyClass
{
public UnKnownType
{
}
}
Since the Student and School types do not have any relationship between them you could use the object type:
public class MyClass
{
public object SomeProperty { get; set; }
}
and use like this:
MyClass myClass = new MyClass();
myClass.SomeProperty = new Student();
or make the containing class generic:
public class MyClass<T>
{
public T SomeProperty { get; set; }
}
and then you could use like this:
MyClass<Student> myClass = new MyClass<Student>();
myClass.SomeProperty = new Student();
public class MyClass
{
private object myField = null;
public object MyProperty
{
get { /* ... */ }
set { /* ... */ }
}
}

Abstract property with public getter, define private setter in concrete class possible?

I'm trying to create an abstract class that defines a property with a getter. I want to leave it up to derived classes to decide if they want to implement a setter for the property or not. Is this possible?
What I have so far:
public abstract class AbstractClass {
public abstract string Value { get; }
public void DoSomething() {
Console.WriteLine(Value);
}
}
public class ConcreteClass1 : AbstractClass {
public override string Value { get; set; }
}
public class ConcreteClass2 : AbstractClass {
private string _value;
public override string Value {
get { return _value; }
}
public string Value {
set { _value = value; }
}
}
public class ConcreteClass3 : AbstractClass {
private string _value;
public override string Value {
get { return _value; }
}
public void set_Value(string value) {
_value = value;
}
}
In ConcreteClass1, I get an error on the set. It can't override set_Value because no overridable set accessor exists in AbstractClass.
In ConcreteClass2, I get an error on both Value's because a member with the same name is already declared.
ConcreteClass3 doesn't give an error, but even though Value's set accessor would be compiled into set_Value, it doesn't work the other way around. Defining a set_Value does not mean that Value gets a set accessor. So I can't assign a value to a ConcreteClass3.Value property. I can use ConcreteClass3.set_Value("value"), but that's not what I'm trying to achieve here.
Is it possible to have the abstract class demand a public getter, while allowing an optional setter to be defined in a derived class?
In case you'r wondering, this is just a theoretical question. I don't have a real situation where something like this is needed. But I can imagine an abstract class that doesn't care how a property gets set, but that does need to be able to get the property.
Unfortunately, you can't do exactly what you want. You can do this with interfaces though:
public interface IInterface {
string MyProperty { get; }
}
public class Class : IInterface {
public string MyProperty { get; set; }
}
The way I would do it is to have a separate SetProperty method in the concrete classes:
public abstract class AbstractClass {
public abstract string Value { get; }
}
public class ConcreteClass : AbstractClass {
private string m_Value;
public override string Value {
get { return m_Value; }
}
public void SetValue(string value) {
m_Value = value;
}
}
Found a solution: How to override a getter-only property with a setter in C#?
public abstract class A
{
public abstract int X { get; }
}
public class B : A
{
public override int X { get { return 0; } }
}
/*public class C : B //won't compile: can't override with setter
{
private int _x;
public override int X { get { return _x; } set { _x = value; } }
}*/
public abstract class C : B //abstract intermediate layer
{
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
public class D : C //does same thing, but will compile
{
private int _x;
protected sealed override int XGetter { get { return this.X; } }
public new virtual int X { get { return this._x; } set { this._x = value; } }
}
D is now equivalent to a class inheriting from B while also being able to override in a setter.
You can just use protected access modifier instead. Because of inheritance you are not allowed to use private. It looks like so:
public abstract class A
{
public abstract int prop { get; protected set; }
}
public abstract class B : A
{
public override int prop { get; protected set; }
}
Not very elegant, but it's the closest you can get without doing something like you have in concreteclass3
public class Concrete : AbstractClass
{
public new void DoSomething()
{
Console.WriteLine(Value);
}
}
public abstract class AbstractClass
{
protected AbstractClass()
{
try
{
var value = Value;
}
catch (NotImplementedException)
{
throw new Exception("Value's getter must be overriden in base class");
}
}
public void DoSomething()
{
Console.WriteLine(Value);
}
/// <summary>
/// Must be override in subclass
/// </summary>
public string Value { get { throw new NotImplementedException(); } }
}

Categories