Using constructor in a child class throws an error - c#

I've been studying how to use inherited classes in C#. I have no clue whatsoever as to why my code in invalid.
What I'm trying to achieve is to have one class (Child) that inherits from another (Parent). Each class should have its own constructor. The error reads:
<< CS7036 There is no argument given that corresponds to the required
<< formal parameter 'isOpen' of 'Parent.Parent(bool)'
public class Parent
{
internal bool IsOpen;
public Parent(bool isOpen)
{
this.IsOpen = isOpen;
}
}
public class Child : Parent
{
public Child(bool isOpen)
{
this.IsOpen = isOpen;
}
}

You need to pass it down to the parent via the base keyword:
public class Parent
{
internal bool IsOpen;
public Parent(bool isOpen)
{
this.IsOpen = isOpen;
}
}
public class Child : Parent
{
public Child(bool isOpen)
: base(isOpen)
{
}
}

You need to call the constructor of the base class (Parent) in your subclass:
public class Parent
{
internal bool IsOpen;
public Parent(bool isOpen)
{
this.IsOpen = isOpen;
}
}
public class Child : Parent
{
public Child(bool isOpen) : base(isOpen)
{
}
}
This also removes the need for you to set IsOpen again in the constructor of Child.

Related

How to set a fixed value to fields to a type?

If I have this hierarchy of classes:
Class Shape
{
public bool closedPath;
}
class Circle : Shape
{
}
class Line: Shape
{
}
Here I know that all circles are closed paths.
How to set the value of closedPath field to these defaults without the need to assign its value when instantiating an object of that said class?
You can declare your closedPath as a virtual read-only property and then define it in descendant classes:
class Shape
{
public virtual bool closedPath {get;}
}
class Circle : Shape
{
public override bool closedPath => true;
}
class Line: Shape
{
public override bool closedPath => false;
}
Things you might also consider are:
changing your Shape class to the abstract class or to the IShape interface.
You can also achieve the same result with a read-only field and initialize that field in the constructor.
You can pass a value to the base constructor:
class Shape
{
public bool closedPath;
public Shape(bool closedPath)
{
this.closedPath = closedPath;
}
}
class Circle : Shape
{
public Circle()
: base(true)
{
}
}
class Line : Shape
{
public Line()
: base(false)
{
}
}
Then you'd get:
void SomeMethod()
{
Shape circle = new Circle();
Console.WriteLine(circle.closedPath); // True
Shape line = new Line();
Console.WriteLine(line.closedPath); // False
}

AccessibleObject implementation for custom controls

I have a very simple controls library for Windows Forms and I am getting problems to implement accessibility.
I have a very simple Form with a member that contains a list of controls of my library, and I have overriden the CreateAccessibilityInstance:
public partial class Form1 : Form
{
protected override AccessibleObject CreateAccessibilityInstance()
{
return new AccessibleForm(this);
}
public MyContainer MyContainer;
public Form1()
{
InitializeComponent();
MyContainer = new MyContainer();
MyContainer.Controls.Add(new MyButton());
}
}
The AccessibleForm class looks like:
public class AccessibleForm: Control.ControlAccessibleObject
{
private Form1 form1;
public AccessibleForm(Form1 owner):base(owner)
{
this.form1 = owner;
}
public override AccessibleObject GetChild(int index)
{
return this.form1.MyContainer.Controls[index].AccessibilityObject;
}
public override int GetChildCount()
{
return this.form1.MyContainer.Controls.Count() ;
}
}
MyContanier and MyButton classes inherits from BaseControl, they are very easy:
public class BaseControl : Control
{
protected override AccessibleObject CreateAccessibilityInstance()
{
return new AccessibleObject();
}
}
public class MyContainer:BaseControl
{
public List<BaseControl> Controls { get; set; }
public MyContainer()
{
this.Controls = new List<BaseControl>();
}
}
public class MyButton:BaseControl
{
}
The point is that when I run the UIVerify tool to see if my controls are generating the correct structure I can not see them:
Another point is, that if I modify the GetChild method from AccessibleForm class in this way:
public override AccessibleObject GetChild(int index)
{
return new AccessibleObject();
////return this.form1.MyContainer.Controls[index].AccessibilityObject;
}
I can see a node on the UIVerify:
But modifying the GetChild method to return a custom accessible object it shows me nothing.
Why are not my controls on the tree?
I do not know what I am missing.
Override Name,value,Role in AccessibleForm class

In C#, the interface can be instantiated?

I'm reading the code in here. I find that private ITreeModel _model; in TreeList.cs:
namespace Aga.Controls.Tree
{
public class TreeList: ListView
{
#region Properties
//...
private ITreeModel _model;
public ITreeModel Model
{
//...
}
//...
}
}
and the ITreeModel is a interface in ITreeModel.cs:
namespace Aga.Controls.Tree
{
public interface ITreeModel
{
/// <summary>
/// Get list of children of the specified parent
/// </summary>
IEnumerable GetChildren(object parent);
/// <summary>
/// returns wheather specified parent has any children or not.
/// </summary>
bool HasChildren(object parent);
}
}
the _model is a instantiated object?
Edited:
TreeList.cs:
namespace Aga.Controls.Tree
{
public class TreeList: ListView
{
#region Properties
/// <summary>
/// Internal collection of rows representing visible nodes, actually displayed in the ListView
/// </summary>
internal ObservableCollectionAdv<TreeNode> Rows
{
get;
private set;
}
private ITreeModel _model;
public ITreeModel Model
{
get { return _model; }
set
{
if (_model != value)
{
_model = value;
_root.Children.Clear();
Rows.Clear();
CreateChildrenNodes(_root);
}
}
}
private TreeNode _root;
internal TreeNode Root
{
get { return _root; }
}
//....
}
}
}
Edited2:
Somewhere:
public partial class RegistrySample : UserControl
{
public RegistrySample()
{
InitializeComponent();
_tree.Model = new RegistryModel();
}
}
class RegistryModel : ITreeModel
Of course you can do this, but underlying object must implement this Interface. So you can do something like
ITreeModel _model = new TreeModel();
Where
public class TreeModel:ITreeModel
{
...
}
You can never instantiate an interface in C# directly, but yes you can instantiate a subclass implementing that interface. For example:
interface IShape
{
//Method Signature
void area(int r);
}
public class Circle : IShape
{
//method Implementation
void area(int r)
{
float area;
area = 3.14 * r * r;
Console.WriteLine("The area of the circle is: {0}",area);
}
}
public class Shapes
{
public static void Main() {
//Uncommenting the following line will cause compiler error as the
// line tries to create an instance of interface.
// interface i = new IShape();
// We can have references of interface type.
IShape i = new Circle();
i.area(10);
}
}
It's implemented somewhere else in the code. If you call _model.GetType().ToString() you will see it is not just an interface.
But to answer your question correctly, YES, an interface can be instantiated. Some of you may think "no it can't", but it can be done (with some COM hacks):
class Foo : IFoo
{
readonly string name;
public Foo(string name)
{
this.name = name;
}
string IFoo.Message
{
get
{
return "Hello from " + name;
}
}
}
// these attributes make it work
// (the guid is purely random)
[ComImport, CoClass(typeof(Foo))]
[Guid("d60908eb-fd5a-4d3c-9392-8646fcd1edce")]
interface IFoo
{
string Message {get;}
}
//and then somewhere else:
IFoo foo = new IFoo(); //no errors!
Here is my source.
That _model should contain an instance of a class that implements that ITreeModel interface (or it's null).
From Interfaces (C# Programming Guide)
An interface can't be instantiated directly. Its members are
implemented by any class or struct that implements the interface.
No _model is an interface reference to instance of a class object which implements ITreeModel
_model is a member of TreeList and that means that you can create an instance of a class and then it will contain an instance of some class. for example
_model = new TreeModel();
will make _model contain an instance
but you cannot do
_model = new ITreeModel();
because ITreeModel is and interface and you cannot create an instance of an interface

How to get "new" parameter of base class?

I'm deriving a class from a parameterless-constructor class like this:
public class Base
{
public Base(Panel panel1)
{
}
}
public class Derived : Base
{
public Derived() : base(new Panel())
{
//How do I use panel1 here?
}
}
How can I refer to panel1 in Derived?
(Simple workarounds welcome.)
Adil's answer assumes that you can modify Base. If you can't, you can do this:
public class Derived : Base
{
private Panel _panel;
public Derived() : this(new Panel()) {}
private Derived(Panel panel1) : base(panel1)
{
_panel = panel1;
}
}
You need to define Panel in Base, you can use protected instead of public as well. Read more aboud access speicifiers here
public class Base
{
public Panel panel {get; set;};
public Base(Panel panel1)
{
panel = panel1;
}
}
public class Derived : Base
{
public Derived() : base(new Panel())
{
// this.panel
}
}
public class Base
{
// Protected to ensure that only the derived class can access the _panel attribute
protected Panel _panel;
public Base(Panel panel1)
{
_panel = panel1;
}
}
public class Derived : Base
{
public Derived() : base(new Panel())
{
// refer this way: base.panel
}
}
Further if you want to provide only a get and not a set for the derived classes you can do this:
public class Base
{
// Protected to ensure that only the derived class can access the _panel attribute
private Panel _panel;
public Base(Panel panel1)
{
_panel = panel1;
}
protected Panel Panel
{ get { return _panel; } }
}
public class Derived : Base
{
public Derived() : base(new Panel())
{
// refer this way: base.Panel (can only get)
}
}
Two ways:
public class Derived : Base
{
Panel aPanel;
public Derived() : this(new Panel()) {}
public Derived(Panel panel) : base(aPanel)
{
//Use aPanel Here.
}
}
OR
public class Base
{
protected Panel aPanel;
public Base(Panel panel1)
{
aPanel = panel1
}
}

How to define a virtual getter and abstract setter for a property?

This is essentially what I want to do:
public abstract class Uniform<T>
{
public readonly int Location;
private T _variable;
public virtual T Variable
{
get { return _variable; }
}
}
public class UniformMatrix4 : Uniform<Matrix4>
{
public override Matrix4 Variable
{
set
{
_variable = value;
GL.UniformMatrix4(Location, false, ref _variable);
}
}
}
The getter for Variable will be the same across all derived classes, but the setter needs to be different.
In fact... I'd prefer not to have derived classes at all (it's only one function call that will differ for each type) but I can't think of how else to do it.
Edit: If it wasn't clear what the problem I'm having is, I'm getting a syntax error:
'UniformMatrix4.Variable.set': cannot override because 'Uniform.Variable' does not have an overridable set accessor
And I'm not sure how to create an "overridable set accessor"... virtual and abstract don't seem to be allowed on the setter.
It's not possible to do this in C#, but as a workaround you could do this. It would involve calling an abstract setter function which could be overridden by derived classes, while leaving the standard get intact. Would this work?
public abstract class Uniform<T>
{
public readonly int Location;
protected T _variable;
public T Variable
{
get { return _variable; }
set { SetVariable(value); }
}
protected abstract void SetVariable(T value);
}
public class UniformMatrix4 : Uniform<Matrix4>
{
public override void SetVariable(Matrix4x4 value)
{
_variable = value;
GL.UniformMatrix4(Location, false, ref _variable);
}
}
You will need to do this:
public abstract class Uniform<T>
{
public readonly int Location;
public virtual T Variable
{
get; set;
}
}
public class UniformMatrix4 : Uniform<Matrix4>
{
public override Matrix4 Variable
{
get
{
return base.Variable;
}
set
{
base.Variable = value;
GL.UniformMatrix4(Location, false, ref value);
}
}
}
As I understand, the behaviour will be the expected.
Hope it helps.
It is not possible to do this in C#. You have to add a setter to the base class, and make it throw an "Invalid Operation" exception.

Categories

Resources