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();
}
}
Related
So I have a maybe naive question about object inheritance and constructors. Basically, a class has an object:
public class ParentClass{
protected Parent item;
And the accessor goes as follows:
public Parent ItemValue
{
set
{
item = value;
}
get
{
return item;
}
}
Now I want to inherit the class:
public class ChildClass:ParentClass
{
public new Child item;
}
Now, whenever I access the Child item through the inherited accessor it, of course, returns the item as the Parent class instead of Child class. Is there a way to make it return the item as Child class without overwriting the accessor in the ChildClass?
No, you can't change type of base property to return different (derived) type.
Standard workaround if you don't need inheritance - generic class:
public class ParentClass<T> {
public T ItemValue { get; set; }
...
}
public class ChildClass : ParentClass<ChildClass>
{
...
}
Note that if you just need access to item in its own class you can just have virtual property:
public class Parent { }
public class Child:Parent { public string ChildProperty; }
public abstract class ParentClass
{
public abstract Parent ItemValue { get; }
}
public class ChildClass : ParentClass
{
Child item;
public override Parent ItemValue { get {return item;} }
public void Method()
{
// use item's child class properties
Console.Write(item.ChildProperty);
}
}
If you are just wanting to have Item of a type defined by your descendent class, you can do this
public class ParentClass<T>{
protected T item;
public T ItemValue
{
set
{
item = value;
}
get
{
return item;
}
}
}
public class ChildClass:ParentClass<Child>
{
// No need to create a new definition of item
}
However depending on your problem, your next question will be how can I add ChildClass1 and ChildClass2 to the same List/Array/Dictionary/etc when they have different T's.
Take a step back for a minute. Does your ParentClass really need to know what item is?
(Ab)Using the Animal example above, your Horse might have a Walk(), Trot(), Canter() or Gallop() methods but a Duck might have a Swim() or Waddle() methods.
Perhaps your logic says something like, iterate my animal collection and tell the swimmers to swim. In this case, you could declare:
using System;
using System.Collections.Generic;
public class Program
{
public class Location {}
public interface ISwimmer{
void SwimTo(Location destination);
}
public class Animal {} // whatever base class properties you need
public class Duck : Animal, ISwimmer
{
public void SwimTo(Location destination)
{
Console.WriteLine("Implement duck's swim logic");
}
}
public class Fish : Animal, ISwimmer
{
public void SwimTo(Location destination)
{
Console.WriteLine("Implement fish's swim logic");
}
}
public class Giraffe : Animal {}
public static void Main()
{
List<Animal> animals = new List<Animal>
{
new Duck(),
new Fish(),
new Giraffe()
};
foreach (Animal animal in animals)
{
ISwimmer swimmer = animal as ISwimmer;
if (swimmer==null) continue; // this one can't swim
swimmer.SwimTo(new Location());
}
}
}
I have this class hierarchy:
public abstract class AClass : SomeFrameworkClass {
[WorkOnThisProperty(With.Some.Context)]
private MyObject MyProperty { get; set; }
public override void OnSomethingHappened() {
ExternalFramework.WorkOn(this);
}
}
public class BClass : AClass {
// ... Snip ...
}
ExternalFramework is operating on this: an instance of BClass but i need it to operate on this as an instance of AClass because ExternalFramework only works on the type of the object passed in and does not go up the inheritance hierarchy. How can i downcast this into AClass so ExternalFramework can actually detect MyProperty?
I've tried casting this to object and then to AClass, and casting it directly to AClass but as the cast is unnecessary it doesn't seem to run. What can i do about this?
EDIT: ExternalFramework is Cheeseknife. I am trying to inject a couple views into a base fragment class that has all the reusable logic while child fragment classes implement some specific behaviour tuning.
The problem is that all private members of a class can only be accessed inside of the same class.
With this code:
class A { private string Property { get; set; } }
class B : A { public string Proxy => Property; }
We'll get compilation error because class B cannot access private property from class A, but if change keyword to protected :
class A { protected string Property { get; set; } }
It should work.
I'm not sure the title reflect the question that I was meant, but..
Let's say I have two classes, Entity and Component:
public abstract class Entity
{
private List<Component> _components = new List<Component>();
public void AddComponent<T>()
where T : Component
{
T component = (T)Activator.CreateInstance(typeof(T));
component.Owner = this;
_components.Add(component);
}
}
public abstract class Component
{
public Entity Owner { get; protected set; }
public abstract void Update();
}
As you may notice, above classes are abstract classes which mean is not intended for direct use. However, on the later stage of development, I'm aware that some Component require ability that only attachable / Added by specific class that inherited to Entity class.
So, I added a class Component<T> that inherit Component:
public abstract class Entity
{
private List<Component> _components = new List<Component>();
public void AddComponent<T>()
where T : Component
{
T component = (T)Activator.CreateInstance(typeof(T));
component.Owner = this;
_components.Add(component);
}
}
public abstract class Component
{
public Entity Owner { get; protected set; }
public abstract void Update();
}
public abstract class Component<T> : Component
{
// I hide the base.Owner with new keyword
// feel free to suggest me in case there is better approach to do this
new public T Owner
{
get { return (T)base.Owner; }
protected set { base.Owner = value; }
}
}
And now, let's say I have Foo, Bar and Processor class:
public class Foo : Entity
{
public int FooValue { get; set; }
}
public class Bar : Entity
{
public int BarValue { get; set; }
}
public class Processor : Component<Foo>
{
public override void Update()
{
Owner.FooValue = 10;
}
}
What I want to do is to make Processor class only add-able by Foo object. Currently AddComponent ignore it, so I don't know how to do that:
var foo = new Foo();
var bar = new Bar();
foo.AddComponent<Processor>(); // OK
bar.AddComponent<Processor>(); // Compiler should give an error at this point
I also tried to do this:
public void AddComponent<T, X>()
where T : Component<X>
where X : Entity
{
T component = (T)Activator.CreateInstance(typeof(T));
component.Owner = this;
_components.Add(component);
}
However, it require me to explicitly specify the X constraint:
foo.AddComponent<Processor, Foo>();
bar.AddComponent<Processor, Bar>(); // Error, but the syntax is weird!
Any ideas?
Your post isn't clear on what constraints, if any, you have on your basic Entity and Component classes. So I don't know if the below will be feasible in your scenario. That said, I believe that if it's not, you won't be able to do what you want because otherwise the generic type parameters won't be known by the compiler.
The solution, absent any other constraints, is to make your Entity class generic, and provide the sub-class type itself as the type parameter:
class Entity { }
class Entity<T> : Entity where T : Entity<T>
{
public void AddComponent<U>(U value) where U : Component<T> { }
}
class Component<T> where T : Entity { }
class Foo : Entity<Foo> { }
class Bar : Entity<Bar> { }
class P : Component<Foo> { }
I know it looks weird. But you're basically asking for a self-referential graph of generic type dependencies, and in C# code the above is what that looks like.
You can call the AddComponent() method using type inference (so no generic parameter needed). If you try to call it with the wrong type of Component<T> object, you'll get a compiler error:
Foo foo = new Foo();
Bar bar = new Bar();
P p = new P();
foo.AddComponent(p);
bar.AddComponent(p); // CS0311
Note: I would strongly recommend against hiding class members. It doesn't really affect your question as stated (i.e. you could have left that detail out completely), but having two different properties with the same name is just asking for bugs. If you must use hiding, IMHO you should at least have the new property use the hidden property. E.g.:
class Component
{
public Entity Owner { get; protected set; }
}
class Component<T> : Component where T : Entity
{
new public T Owner
{
get { return (T)base.Owner; }
set { base.Owner = value; }
}
}
You won't get compile-time checking on assignments to the non-generic Component.Owner property, but at least you'll get a run-time error if some code tries to dereference the Owner property as the generic version, if and when the wrong type was assigned by the base type for some reason.
Say I have code out there like this:
public class Base // I cannot change this class
{
public string Something { get; private set; }
public string Otherthing { get; set; }
public static Base StaticPreSet
{
get { return new Base { Something = "Some", Otherthing = "Other"}; }
}
public static Base StaticPreSet2
{
get { return new Base { Something = "Some 2", Otherthing = "Other 2"}; }
}
}
public class SubClass : Base // I can change this class all I want.
{
public string MoreData { get; set; }
// How can I wrap the PreSets here so that they return SubClass objects?
// Something like this:
public static SubClass MyWrappedPreset
{
get
{
// Code here to call the base preset and then use it as the
// base of my SubClass instance.
}
}
}
What makes this complicated is the Something property. It has a private setter. So I can't set it in the subclass. The only way it can be set is is via the preset properties.
Is there a way to wrap the StaticPreSet property in my SubClass so that it will return an object of type SubClass?
// I cannot change this base class.
Given that you can't change the base class, there is no way to cause it to change behavior (ie: return a different class at runtime).
If you could influence the design of the base class static methods, you could redesign it in a way to be flexible enough to provide this functionality. However, without changing it, this won't work.
Edit in response to edit:
You could create a new static method that does what you are showing, like so:
public static SubClass MyWrappedPreset
{
get
{
// Code here to call the base preset and then use it as the
// base of my SubClass instance.
Base baseInstance = Base.StaticPreSet;
SubClass sc = new SubClass(baseInstance); // Create a new instance from your base class
return sc;
}
}
However, this provides a completely new, unrelated property - you'd have to access it via SubClass.MyWrappedPreset, not the Base class.
Static fields in a class "have nothing to do with it".
Basically, except access to private static fields, id doesn't matter in which class you put them - they behave the same.
If you inherit a class, and you declare another static field with the same name of a static field on the base class, you will simply 'hide' it. Example for you:
using System;
public class Base // I cannot change this class
{
public string Something { get; set; }
public string Otherthing { get; set; }
public static Base StaticPreSet
{
get { return new Base { Something = "Some", Otherthing = "Other"}; }
}
public static Base StaticPreSet2
{
get { return new Base { Something = "Some 2", Otherthing = "Other 2"}; }
}
}
public class SubClass : Base // I can change this class all I want.
{
public string MoreData { get; set; }
public static SubClass StaticPreSet2
{
get { return new SubClass { Something = "inherited", Otherthing=""}; }
}
}
public class Test
{
public static void Main()
{
Console.WriteLine(SubClass.StaticPreSet2.Something);
}
}
Will write "inherited".
I have a need where I have to add some new fields to an existing class along with all its existing fields/attributes.
So whenever my derived class is filled by DAL, I will be filling all fields of base class as well. Currently, I am doing it like this but not sure this is the right way ? Please give me an example. Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
public class Employee
{
private int _id;
private int _name;
public int ID
{
set { _id=value;}
get { return _id;}
}
public int Name
{
set { _name=value;}
get { return _name;}
}
protected void SetName ()
{
_name=value;
}
protected void SetID()
{
_id=value;
}
}
public class EmployeeWithDepartmentName:Employee
{
private string _deptName;
public string DeptName
{
set { _deptName=value; }
}
public setBaseEmpName()
{
base.SetName();
}
public setBaseID()
{
base.SetID();
}
}
Everything in a base class can automagically be accessed from derived classes without doiing anything, just use the property/method name directly.
public class MyBase
{
public string UserName {get;set;}
}
public class MyClass : MyBase
{
public void DoSomething()
{
Console.WriteLine("UserName: {0}", UserName);
UserName = "Anders";
}
}
You can also do this:
MyClass myClass = new MyClass();
myClass.UserName = "Rune";
Protected means that only derived classes can access the property/method. Public means that everyone can access the properties/methods.
Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
It's not two objects, it's one object created from two different classes (that's how inheritance works).
Read this article about inheritance: http://www.csharp-station.com/Tutorials/lesson08.aspx