Initialize parent class array member in child class in C# - c#

Is it possible in C# to write something like this that actually works (this compiles and runs, but doesn't work properly)?
public abstract class Foo
{
public int[] a;
}
public class Bar : Foo
{
public int[] a = new int[123];
}
Or do I have to use this (works fine, but doesn't seem as nice as the above code)?
public abstract class Foo
{
public int[] a;
public void Init(int size)
{
a = new int[size];
}
}
public class Bar : Foo
{
public Bar()
{
Init(123);
}
}

Based on your comment above:
The intention is to have the child class set the array size.
It sounds like what you're looking for is called a constructor. You would use it to define the required values for creating an instance of an object, and use those values to build the object.
Your base class would require the value, something like this:
public abstract class Foo
{
public int[] a;
public Foo(int size)
{
a = new int[size];
}
}
So now one needs to supply the value for the constructor. The child class can supply the value from its own constructor easily using constructor chaining:
public class Bar : Foo
{
public Bar(int size) : base(size) { }
}

The Bar.a hides inherited base member (Foo.a). To make this works properly, firstly, you need to change your base member from field to property and secondly declare it as abstract and then override it in your derived class. Something like this:
public abstract class Foo
{
public abstract int[] a { get; set; }
}
public class Bar : Foo
{
public override int[] a { get; set; }
}
Or if you only want to have the child class set the array size use constructor in your derived class like this:
public abstract class Foo
{
public int[] a;
}
public class Bar : Foo
{
public Bar()
{
a = new int[123];
}
}

Related

Casting a Super Class in to a Sub Class

I have a class that looks like:
public class MySuperClass
{
public void PrintValue()
{
print("SUPER Class");
}
}
I then have another class that looks like:
public class MySubClass : MySuperClass
{
public void PrintSubValue()
{
print("SUB Class");
}
}
Then, I have a situation where I have a third class that looks like:
public class MyOtherClass
{
public MyOtherClass(MySuperClass someSubClass)
{
someSubClass.PrintSubValue();
}
}
It won't compile... As is to be expected.
Now if I change MyOtherClass to look like:
public class MyOtherClass
{
public MyOtherClass(MySuperClass someSubClass)
{
someSubClass = (MySubClass) someSubClass;
someSubClass.PrintSubValue();
}
}
It still won't compile... This I didn't expect.
Why am I unable to cast a Super Class to a Sub Class? And how can I get around this issue?
Why am I unable to cast
You are able to cast, but then you assign it back to MySuperClass someSubClass which implicitly casts it back to MySuperClass.
Use
var castedSomeSubClass = (MySubClass)someSubClass;
or
MySubClass castedSomeSubClass = (MySubClass)someSubClass;

c# get only child properties without parent class properties

Is there a way, and not using reflection, of elegant get only child propeties of an object?
For example:
class A
{
public string PropA;
}
class B : A
{
public string PropB;
}
class C
{
var classB_instance = new B();
/* Only class B properties without parent so B.PropB; but no B.PropA;
}
I know it would be possible with reflection, but if this can be avoided?
You could create a specific interface for your inherited class like say
interface ISpecificB {
string PropB;
}
and then Create your class like
public class A {
public string PropA;
}
public class B: A, ISpecificB {
public string PropB;
}
and only make the variable as specific as ISpecificB when creating it or returning it from a function
ISpecificB classB = new B();
classB.PropA // shouldn't be available
However, classB could still be casted as B or A which would give access to the propA and it might increase complexity in your solution
Whether you can do this way ?
class A
{
private string PropA;
}
class B : A
{
public string PropB;
}
class C
{
var classB_instance = new B();
}
You could mark PropA as private, look at https://msdn.microsoft.com/en-us/library/ms173121.aspx:
private
The type or member can be accessed only by code in the same class or struct.
just a short note: most of the time, I use reflection to do exactly the opposite: access things I am not allowed, for example, because they are private... ;-) reflection is not a "tool" to hide something, AFAIK. it opens every door which is usually locked ;-)
You can use the protected accessibility modifier:
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.
public class A
{
protected string PropA { get; set; }
}
public class B : A
{
public string PropB { get; set; }
}
public class C
{
var classB_instance = new B();
//You can't access classB_instance.PropA
}
Declare variable PropA of Class A as private variable(as show in below code):
class A
{
private string PropA;
}

Why can't I access a constant from an object?

public class Foo
{
public const int type = 1;
}
Why can't i do this? Is there a reason behind it or am I trying to access the constant in a wrong way?
new Foo().type;
I know I can do Foo.type but given my scenario, I cant do that. For example if I have two class which inherit from a base class like this:
public class Base
{
...
}
public class Foo : Base
{
public const int type = 0;
}
public class Bar : Base
{
public const int type = 1;
}
public static void printType(Base b)
{
Console.WriteLine(b.type);
}
I would want to get the type property of the class sent through the printType() function but I cant since I can only access the type from the Class, not the object its self.
A work around would be to do
if(b is Foo){
Console.Write(Foo.type);
}elseif....
but this seems stupid and not viable if you have many sub classes of Base
Solution
I ended up using readonly instead of const like this:
public readonly int type = 0;
Yes, you're trying to access it in the wrong way. A constant isn't associated with an instance of a type - it's associated with the type itself. So you want:
int x = Foo.type;
Basically, const members are implicitly static, and C# doesn't let you access static members as if they were instance members, via a value. (Note that in .NET naming conventions, it should be Type rather than type.)
EDIT: Now that you've explained the actual situation, it appears you're trying to use polymorphism, which won't work for constants. So instead, you should have an abstract property in the base class, implemented in subclasses.
public abstract class Base
{
public abstract int Type { get; }
}
public class Foo : Base
{
public override int Type { get { return 0; } }
}
public class Bar : Base
{
public override int Type { get { return 0; } }
}
Alternatively, just have a normal property in the base class which is populated via the base class constructor:
public class Base
{
private readonly int type;
public int Type { get { return type; } }
protected Base(int type)
{
this.type = type;
}
}
public class Foo : Base
{
public Foo() : base(0) {}
}
public class Bar : Base
{
public Bar() : base(1) {}
}
If you just want something to identify the dynamic (most-derived) type of the object passed in, that's built into .NET, via the Object.GetType() method.
public static void printType(Base b)
{
Console.WriteLine(b.GetType().Name);
}
Of course, this isn't quite the same as having attached data under your control. You can, however, use a Dictionary<Type, T> to associate data of arbitrary type with the various subclasses. It would be reasonable to use the subclass type initializer to install new entries into such a dictionary.
public class Base
{
static internal readonly Dictionary<System.Type, int> TypeMap =
new Dictionary<System.Type, int>();
}
public class Foo : Base
{
static Foo { TypeMap.Add(typeof(Foo), 0); }
}
public class Bar : Base
{
static Bar { TypeMap.Add(typeof(Bar), 1); }
}
public static void printType(Base b)
{
Console.WriteLine(Base.TypeMap[b.GetType()]);
}
This WILL be a bit slower than the field-per-object method, however it doesn't add any extra storage per-object.

How to Get Base Class Instance from a Derived Class

I don't know if this is possible, but I am trying to get the Base Class instance from a Derived Class. In C#, I can use the base keyword to access properties and methods of the Base Class (of course), but I want to use base itself. Attempting to do so results in a "Use of keyword 'base' is not valid in this context" error.
Example Code
public class SuperParent
{
public int SPID;
public SuperParent()
{
}
}
public class SubChild : SuperParent
{
public SubChild(int pSPID)
{
base.SPID = pSPID;
}
public int BaseSPID
{
get
{
SuperParent sp = base;
return sp.SPID;
}
}
}
If you're working with an instance of the derived class, there is no base instance.
An example:
class A
{
public void Foo() { ... }
}
class B : A
{
public void Bar() { ... }
}
What is not possible within B:
public void Bar()
{
// Use of keyword base not valid in this context
var baseOfThis = base;
}
You can do something like this:
public void Bar()
{
base.Foo();
}
And you can add another method like
public A GetBase()
{
return (A)this;
}
And then you can
public void Bar()
{
var baseOfThis = GetBase();
// equal to:
baseOfThis = (A)this;
}
So this GetBase() method is probably what you want.
The punchline is: If you have an instance of B, it inherits all properties and the non-overriden behaviour of A, but it does not consist of an instance of B which holds an (hidden but automatic) reference to an instance of A. You can cast your B instance to A, but it remains to be an instance of B.
Well you not provide code for your question, but i supsect you want something like
class Base
{
public virtual void Foo()
{
Console.WriteLine("base");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("derived");
}
//// bad
//public Base MyBase
//{
// get
// {
// return base; // Use of keyword 'base' is not valid in this context
// }
//}
// work but...
public Base MyBase
{
get
{
return (Base)this;
}
}
}
But keep in mind that MyBase is really of type Derived
new Derived().MyBase.Foo(); // output "derived"
the problem hasn't been explained as clearly as it could. however, typically, you may be better to use an abstract base class and methods and then override the required methods. you can then use the base.method as required in this case (otherwise you'll have just spun up an instance of the derived class).
public abstract class foo {
public virtual void bar(){..}
}
public class footwo : foo {
public override void bar(){
// do somethng else OR:
return base.bar();
}
}
}
The derived instance IS the base instance. It's just one object instance in memory.
example:
public class A : B
{
}
var thing = new A();
thing is an instance of an A, and is also an instance of a B.
You could for example, write this line:
B thing2 = thing;
Point 1: if you want to create the base class instance within child class than it does not worth. You already have public things accessible in child.
Point 2: If you have initialized child class and now want to get base class "instance" then how can you get that if it's not initialized(Because now the base class instance is not present in the physical memory, and there is just child class instance there)?
I interpreted what they were asking a bit differently than the other answers here so I figured I would offer my $0.02.
// Create a "Parent" class that has some attributes.
public class Parent
{
public string attribute_one { get; set; }
public string attribute_two { get; set; }
public string attribute_three { get; set; }
}
// Define a class called "Child" that inherits the
// attributes of the "Parent" class.
public class Child : Parent
{
public string attribute_four { get; set; }
public string attribute_five { get; set; }
public string attribute_six { get; set; }
}
// Create a new instance of the "Child" class with
// all attributes of the base and derived classes.
Child child = new Child {
attribute_one = "interesting";
attribute_two = "strings";
attribute_three = "to";
attribute_four = "put";
attribute_five = "all";
attribute_six = "together";
};
// Create an instance of the base class that we will
// populate with the derived class attributes.
Parent parent = new Parent();
// Using reflection we are able to get the attributes
// of the base class from the existing derived class.
foreach(PropertyInfo property in child.GetType().BaseType.GetProperties())
{
// Set the values in the base class using the ones
// that were set in the derived class above.
property.SetValue(parent, property.GetValue(child));
}
The result is a new object populated with the base class properties of the child class.
class Parent
{
private Parent _parent;
public Parent()
{
_parent = this;
}
protected Parent GetParent()
{
return _parent;
}
}
class Child : Parent
{
private Parent _parent;
public Child()
{
_parent = base.GetParent();
}
}

Can I define a property which is available to both the class type and instances of the class?

I have an interface for a base class, and every class that inherits from the base class should have an identifying field which tells the application what kind of object it is.
I wanted to use this property in two different ways:
Without creating an instance of the object
if (someValue == TestA.Id)
return new TestA();
elseif (someValue == TestB.Id)
return new TestB();
And as a property of the interface
void DoSomething(ITest testObject)
{
SomeValue = testObject.Id;
}
Is there an easy way to define the Id field in the interface, but still have it available to use without creating an instance of the class?
Right now I am using the following code. I could add a read-only Id property to the interface which returns the const string, however I was hoping there was a simpler way that I'm just not aware of.
public interface ITest
{
}
public class TestA : ITest
{
public const string Id = "A";
}
In short - no.
In order to be able to do this, you'd need to be able to specify this as a instance property on the interface (and implement it in the instance), and as a static property on the type.
The compiler won't let you do this.
You can put it in the interface, and also have it as a static property. Something like:
interface IInterface { Id { get; } }
class Class : IInterface
{
public static Id { get { return 1; } }
public Id { get { return Class.Id; } }
}
I've faced a similar problem, Rachel, and I've always (unfortunately) resorted to having that factory code rely on reflection to get a "TypeID" public static property on each concrete type... thus making an additional aspect of the contractual interface, but not having it in the C# interface code.
You could do it this way.
public interface ITest
{
SomeValue Id{ get;}
}
public class TestA : ITest
{
public SomeValue Id
{
get {return TestA.StaicId; }
}
public static SomeValue StaticId
{
get {return "This is TestA";}
}
}
if (someValue == TestA.StaticId)
return new TestA();
How about using attributes? Here's a small example of what can be done:
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class IdAttribute : Attribute
{
public IdAttribute(string id)
{
this.Id = id;
}
public string Id { get; set; }
}
public interface IMyInterface
{
}
public abstract class BaseClass : IMyInterface
{
public static string GetId<T>() where T : IMyInterface
{
return ((IdAttribute)typeof(T).GetCustomAttributes(typeof(IdAttribute), true)[0]).Id;
}
}
[Id("A")]
public class ImplA : BaseClass
{
}
[Id("B")]
public class ImplB : BaseClass
{
}
internal class Program
{
private static void Main(string[] args)
{
var val1 = BaseClass.GetId<ImplA>();
var val2 = BaseClass.GetId<ImplB>();
Console.ReadKey();
}
}

Categories