How to pass const arguments to an abstract class parent in C#? - c#

i have wrote the following polymorphic code:
public abstract class A
{
readonly int x;
A(int i_MyInt)
{
x = i_MyInt;
}
}
public abstract class B : A
{
//holds few integers and some methods
}
// concrete object class
public class C : B
{
// holds some variables and mathods
C(int MyInt)
{
// here i would like to initialize A's x
}
}
how can i initialize A's x from C
i tried passing parameters to A's C'tor - but didn't work..
Please Help,
Thanks in advance
Amitos80

You need to add a constructor to B that takes an integer and passes it to A's constructor. You can then call this constructor from C.
public abstract class B : A
{
public B(int myInt) : base(myInt)
{
// other initialization here...
}
}
public class C : B
{
// holds some variables and mathods
public C(int myInt) : base(myInt)
{
// other initialization here...
}
}
A's constructor must also not be private.

Related

Tell in C# that a genericly passed interface extends another interface with a generic parameter

How could I tell in C# that a genericly passed interface extends another interface, which also has a generic parameter?
E.g. how can I tell that the Y has a foo method?
using System;
public class Program
{
public static void Main()
{
B b = new BImplementation();
var c = new C<B>();
c.bar(b);
}
}
public interface A<T> {
T foo();
}
public interface B : A<int> {}
public class BImplementation : B {
public int foo() => 2;
}
public class C<Y> /*where Y : A<T>*/ {
public void bar(Y y) {
//I would like to be able to call y.foo here
//how can I do that?
//I need to somehow describe the Y type parameter,
//that the Y actually has the `T foo()` method from `A<T>
//y.foo();
}
}

Type 'B' does not have a constructor with parameters of types?

I have a class A. While creating class A, I must run class B (and pass an instance of A as a parameter) but when running, I get an error that I cannot initialize the object? What is the cause and how to solve it?
Specific example:
public class A: UserControl
{
private A ()
{
InitializeComponent ();
}
private void InitializeComponent ()
{
B _B1 = new B (this); // error: Type 'B' does not have a constructor with parameters of types
}
}
public class B
{
private class A _classA;
public B (class A a1)
{
_classA = a1;
}
}
Define your Class B like this. You dont define the argument with class.
public class B
{
private A _classA;
public B(A a1)
{
_classA = a1;
}
}
Even then, once you initialize your Class B like this, you will need another method or property to retrieve the value of _classA. (public A ClassA => _classA; perhaps.)
It should be public B (A a1) { _classA = a1; }

C# abstract generic method call

With the abstract following class:
public abstract class A
{
public static string MyMethod()
{
return "a";
}
}
Why can't I built this derived abstract class:
public class B<T> where T : A
{
public void AnotherMethod()
{
var S1 = base.MyMethod(); // not allowed
var S2 = T.MyMethod(); // not allowed
}
}
I don't understand why since MyMethod will be available in type T.
There are two misconceptions in your question that collectively prevent both your attempts from working.
First your B class is not in any way derived from the A class, you have only said that it takes a generic parameter that must inherit from A.
Second as the user #recursive pointed out, static methods do not participate in inheritance so MyMethod would only ever be available as A.MyMethod()
You can make at least your first attempt work if you remove the static modifier and make B inherit from A instead of using generics.
// Removed the static modifier
public abstract class A
{
public string MyMethod()
{
return "a";
}
}
// Made B inherit directly from A
public class B : A
{
public void AnotherMethod()
{
var S1 = base.MyMethod(); //base technically isn't required
}
}
Aside from the fact that A.MyMethod is static, which clearly will not work since anything static does not take part in inheritance, even if you made it not static it still will not work. For example, this will not work either:
public abstract class A {
public string MyMethod() {
return "a";
}
}
public class B<T> where T : A {
public void AnotherMethod() {
var S1 = base.MyMethod(); // Line 1
var S2 = T.MyMethod(); // Line 2
}
}
Why?
You are saying where T : A which means that type T has to be a derived type from A. Your class B<T is not a derived type of A so Line 1 will not work.
But why is Line 2 not working?
T is a type and if T is inheriting A, then objects of type T will be able to do that. If you changed it like this, then it will work:
public abstract class A {
public string MyMethod() {
return "a";
}
}
public class B<T> where T : A {
public void AnotherMethod(T t) {
t.MyMethod();
}
}
public class C : A {
}
public class BClosed : B<C> {
public void Foo(C c) {
c.MyMethod();
this.AnotherMethod(c);
}
}
In the above code, C derives A which was your restriction. Then BClosed closes the generic type saying T is C so now you can call MyMethod of A and AnotherMethod of your generic.
Also, when you have a generic class you should use the generic type otherwise I do not see the use. So this is useless since it has no generic code:
public class B<T> where T : A {
public void AnotherMethod() {
}
}

Block base constructor to child class

I'm sure this question is somewhere else but can't find it.
I have an abstract class that will be the base for other classes.
want for the base class to have its base constructor inaccessible, and for the child classes not being able to edit the behavior, forcing them to use another constructor.
public abstract class BaseClass
{
protected int X;
private BaseClass() { } // Problematic accessor
public BaseClass(int x)
{
X = x;
}
}
public class Child : BaseClass
{
public Child(int x)
{
X = x + 5;
}
}
If I set the BaseClass() base constructor private it doesn't compile, but if I set it to protected, Child can override it.
There is a way to block Child modifying the base constructor?
EDIT: I want the base constructor to be inaccessible outside the class too.
If you don't want do anything in the
BaseClass()
constructor, just remove it (BaseClass has an explicit constructor and that's why doesn't have a default one):
public abstract class BaseClass
{
//TODO: probably you want a property to read X
private int X; // <- private looks better for fields
public BaseClass(int x)
{
X = x;
}
}
As for Child class you have to invoke its base constructor, i.e. base(int x):
public class Child : BaseClass
{
public Child(int x)
: base(x + 5) // since X is private, let's move logic into the call
{
}
}
You need to use the correct base class constructor to do what you want:
public class Child : BaseClass
{
public Child(int x) : base(x)
{
X = X + 5;
}
}
Note that the Child constructor body now uses the protected field X, not the parameter x.
Just omit the parameter-less constructor altogether. Now, every derived class is forced to call public BaseClass(int x).

Parent does not contain constructor that takes 0 arguments

If I have this code in C#:
public abstract class Parent
{
private int x;
public Parent(int x)
{
this.x = x;
}
public abstract void foo;
}
public class Child
{
public override void foo()
{
x = x + 10;
}
}
I get error that:
Parent does not contain constructor that takes 0 arguments.
How can I fix it, without creating non-parametric constructor?
You can create a constructor in Child, e.g.
public Child(int x) : base(x)
{
}
Constructors are not inherited - but if you don't supply any constructors at all, the C# compiler tries to create one equivalent to this:
public Child() : base()
{
}
That's what's failing here, because there isn't a parameterless base constructor to call.
Your derived class constructor doesn't have to have the same parameters as the base class constructor of course - so long as it passes appropriate arguments to a base constructor, that's fine. For example, you could write:
public Child() : base(0) // Default to x = 0
{
}
See my article on constructors for more details.
By manually invoking Parent's constructor:
public class Child: Parent {
public Child( )
: base(0) { }
public override void foo( ) {
x = x + 10;
}
}
That is because there is an Implicit call to a constructor with zero argument.
So you need to add an explicit call:
public Child(int x) : base(x)
{
}
Or instead, you can add zero argument contructor in parent itself:
public parent() { }

Categories

Resources