I have the following classes:
public class A {
public C mObj:
}
public class B : A {
}
public class C {
public int val1;
}
public class D : C {
public int val2;
}
I initialize all the class B instances in a way that inst.mObj = new D();. When I have an instance of class B I would ideally like to access all the members of class D by using mObj, but due to inheritance I can not do it without casting into D first.
I would like class B to have a member object of class D, but I automatically inherit a member from class C. Is there a way to achieve something like that? If not then how is it usually done when a similar structure is required?
It is difficult to determine your exact requirements, but you could try to use generics with type constraints:
public class A<T>
where T : C
{
public T mObj:
}
public class B : A<D>
{
}
public class C
{
public int val1;
}
public class D : C
{
public int val2;
}
In this case the mObj in B will be of type D, so no conversion will be required.
Related
I have two classes, class A and class B.
public class A
{
public int someNumber;
public A(int a)
{
someNumber = a;
}
}
Now class B has a field that is an object of class A. In C++ it is possible to do this:
public class B
{
public A foo;
public B(int a) : foo(a) { }
}
But this doesnt work in C#. So how can one solve this problem in C# without using a default constructor in class A. To be more precise, how is it possible to write a constructor for class B that takes as parameter the someNumber value of foo?
You could try something like this:
public class B
{
public A thing;
public B(int a)
{
thing = new A(a);
}
}
I understand this is not possible in C#, because Generics are not Templates and they are implented differently(processing on runtime rather than during compile):
public class Foo<T> : T
{
}
The question though remains. Is there an equivalent or perhaps an alternative way to achieve this?
In my case I have three different parent classes I want to inherit from, let's call them A, B, C:
public class A {}
public class B {}
public class C {}
Then I have the Foo class, and then MANY more inheriting from Foo but each of them needing only one of the A, B, C:
public class X : Foo<A> {}
public class Y : Foo<B> {}
public class Z : Foo<C> {}
So class X needs all the functionality in Foo and all the functionality in A, Y from Foo and B and so on...
How do I do this in C#?
I suppose you cannot modify the A, B and C classes (otherwise you could just inherit all of them from Foo), therefore this is my idea:
I would define "Foo" as an interface (that I would call "IFoo"):
public interface IFoo {}
and implement all its methods as Extension methods:
public static class IFooExtension
{
public static void Method1(this IFoo f) {
// do whatever here;
}
}
then I'd declare the further classe as follow:
public class X : A, IFoo {}
public class Y : B, IFoo {}
public class Z : C, IFoo {}
The only issue (if it is an issue) is that you can implement whatever method you want, but no properties.
If class X: Foo<A> { } needs all the functionality of Foo and A, then simply expose A as property and you will have it:
public class Foo<T> where T : new()
{
public T Bar { get; } = new T();
public void FooMethod() => Console.WriteLine("Foo method");
}
public class A
{
public void AMethod() => Console.WriteLine("A method");
}
public class X : Foo<A>
{
}
class Program
{
static void Main(string[] args)
{
var x = new X();
x.FooMethod();
x.Bar.AMethod(); // access via property
}
}
I have an outer class with an inner class like this :
class A
{
public class B
{
public int number;
}
}
I think inner class is useful because I can call my "number" field like this :
A.B.number = X; but I can't call it this shape !
I create an instance from A, for example => A a = new A();
I want to access B by a instance directly => a.B.number;
but I can't.
I know if I create a new from B; I can access it, But I want to know how I can call my field in this shape => A.B.number NOT b.number
in brief, how I can access B class by call A class. (not directly B)
Instead of putting the B class description in A you can just put a property in A that is of type B.
public class B
{
public int number;
}
public class A
{
public A()
{
MyB = new B();
}
public B MyB { get; private set; }
}
Then you can do the following
A myA = new A();
int num = myA.MyB.number;
Though I would suggest also making number in B a property as well.
An inner class is just a class, and if you want to refer to its properties you need to have an object of that.
I think,you should make an object of B.
class A
{
public B b = new B();
public class B
{
public int number;
}
}
I wrote this answer to take experts opinion on it.
class A
{
public B b{ get; private set; }
public A()
{
b= new B();
}
public class B
{
public int number;
}
}
A a = new A();
Now you can access
a.b.number;
Class A will not automatically instantiate an instance of class B. You would need to create a property that returned an instance of B.
For example
public class A {
public A() {
this.MyB = new B()
}
public B MyB {get; set;}
}
You could then delegate to B if you wanted to get a property of b directly.
public int BNumber
{
get
{
return MyB.number;
}
}
With that said, why do you want a nested class here? Class B doesn't need to be nested in A for A to have a property of type B. I think you may be conflating class definition with property definition.
How would I override DerivedZ() in the child, without having to specify a U in the base class? The latter solution appears a bit excessive.
public abstract class Z {}
public class DerivedZ : Z
{
public DerivedZ (B someB, int num)
{
// initialize here
}
}
// will not compile
// error: 'B.GetZ(B, int)': no suitable method found to override
// error: 'B' does not implement inherited abstract member 'A<DerivedZ>.GetZ(A<DerivedZ>, int)'
public abstract class A<T> where T : Z
{
public abstract T GetZ (A<T> inputA, int optional=1);
}
public class B : A<DerivedZ>
{
public override DerivedZ GetZ (B someB, int optional=1)
{
return new DerivedZ (someB, optional)
}
}
this works though...
public abstract class A<T,U> where T : Z where U : A<T,U>
{
public abstract T GetZ (U inputA, int optional=1);
}
public class B : A<DerivedZ,B>
{
public override DerivedZ GetZ (B someB, int optional=1)
{
return new DerivedZ (someB, optional);
}
}
You can't use the first form, because it's not properly overriding the method. If you could do that, imagine this code:
public class C : A<DerivedZ> {}
A<DerivedZ> x = new B();
x.GetZ(new C());
That should work fine, after all - A<T>.GetZ is just declared to accept an A<T>, and C is a A<DerivedZ>.
The approach you've shown is fine.
I agree that sometimes it would be useful to be able to say "something of the same type" but it's not part of the C# type system.
Here is my code (just a snippet to expose the problem) :
public class A
{
class B
{
//private class
}
public int nb;
}
Im tired but why can't I access to "nb" in my private class ?
You're gonna need an instance of A in order to access the instance member nb:
public class A
{
class B
{
public B()
{
A a = new A();
int nb = a.nb;
}
}
public int nb;
}
It's possible in java but not in C#.
You need to pass an instance of A to B.
In C# an 'outer' class is just a 'namespace' to the inner class. So the outer class is not being instantiated.
You need to pass an instance of A to B, like so:
public class A
{
class B
{
private A _outerClass;
public B(A outerClass)
{
_outerClass = outerClass;
// Then you can access nb thus:
_outerClass.nb;
}
}
public int nb;
}