In C#, if I have an inherited class with a default constructor, do I have to explicitly call the base class' constructor or will it be implicitly called?
class BaseClass
{
public BaseClass()
{
// ... some code
}
}
class MyClass : BaseClass
{
public MyClass() // Do I need to put ": base()" here or is it implied?
{
// ... some code
}
}
You do not need to explicitly call the base constructor, it will be implicitly called.
Extend your example a little and create a Console Application and you can verify this behaviour for yourself:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyClass foo = new MyClass();
Console.ReadLine();
}
}
class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass constructor called.");
}
}
class MyClass : BaseClass
{
public MyClass()
{
Console.WriteLine("MyClass constructor called.");
}
}
}
It is implied, provided it is parameterless. This is because you need to implement constructors that take values, see the code below for an example:
public class SuperClassEmptyCtor
{
public SuperClassEmptyCtor()
{
// Default Ctor
}
}
public class SubClassA : SuperClassEmptyCtor
{
// No Ctor's this is fine since we have
// a default (empty ctor in the base)
}
public class SuperClassCtor
{
public SuperClassCtor(string value)
{
// Default Ctor
}
}
public class SubClassB : SuperClassCtor
{
// This fails because we need to satisfy
// the ctor for the base class.
}
public class SubClassC : SuperClassCtor
{
public SubClassC(string value) : base(value)
{
// make it easy and pipe the params
// straight to the base!
}
}
It's implied for base parameterless constructors, but it is needed for defaults in the current class:
public class BaseClass {
protected string X;
public BaseClass() {
this.X = "Foo";
}
}
public class MyClass : BaseClass
{
public MyClass()
// no ref to base needed
{
// initialise stuff
this.X = "bar";
}
public MyClass(int param1, string param2)
:this() // This is needed to hit the parameterless ..ctor
{
// this.X will be "bar"
}
public MyClass(string param1, int param2)
// :base() // can be implied
{
// this.X will be "foo"
}
}
It is implied.
A derived class is built upon the base class. If you think about it, the base object has to be instantiated in memory before the derived class can be appended to it. So the base object will be created on the way to creating the derived object. So no, you do not call the constructor.
AFAIK, you only need to call the base constructor if you need to pass down any values to it.
You don’t need call the base constructor explicitly it will be implicitly called, but sometimes you need pass parameters to the constructor in that case you can do something like:
using System;
namespace StackOverflow.Examples
{
class Program
{
static void Main(string[] args)
{
NewClass foo = new NewClass("parameter1","parameter2");
Console.WriteLine(foo.GetUpperParameter());
Console.ReadKey();
}
}
interface IClass
{
string GetUpperParameter();
}
class BaseClass : IClass
{
private string parameter;
public BaseClass (string someParameter)
{
this.parameter = someParameter;
}
public string GetUpperParameter()
{
return this.parameter.ToUpper();
}
}
class NewClass : IClass
{
private BaseClass internalClass;
private string newParameter;
public NewClass (string someParameter, string newParameter)
{
this.internalClass = new BaseClass(someParameter);
this.newParameter = newParameter;
}
public string GetUpperParameter()
{
return this.internalClass.GetUpperParameter() + this.newParameter.ToUpper();
}
}
}
Note: If someone knows a better solution please tells me.
Related
I have a system where an object can take a generic configuration object (think flyweight pattern). I also have a subclass which takes a subclassed configuration object.
In order to access properties that are specific to the subclass configuration object, is it better to maintain a second reference to the subclass or cast to the subclass?
e.g.
class Base {
public BaseConf Conf;
public Base(BaseConf C) {
Conf = C;
}
}
class Derived : Base {
public DerivedConf DerConf; //Create an extra reference, no casting
public Derived(DerivedConf DC) : base(DC) {
DerConf = DC;
}
public void PrintName() {
Console.WriteLine(DerConf.Name);
}
}
class BaseConf {
public BaseConf() {}
}
class DerivedConf : BaseConf {
public string Name;
public DerivedConf(string n) : base() {
Name = n;
}
}
vs.
class Base {
public BaseConf Conf;
public Base(BaseConf C) {
Conf = C;
}
}
class Derived : Base {
public Derived(DerivedConf DC) : base(DC) {}
public void PrintName() {
DerivedConf DerConf = Conf as DerivedConf; //Cast, no extra reference
Console.WriteLine(DerConf.Name);
}
}
class BaseConf {
public BaseConf() {}
}
class DerivedConf : BaseConf {
public string Name;
public DerivedConf(string n) : base() {
Name = n;
}
}
Both have an identical output
I wouldn't want to do either of those and you can get around both by making the Base take a generic, like so:
class Base<T> where T : BaseConf
{
public T Conf;
public Base(T C)
{
Conf = C;
}
}
class Derived : Base<DerivedConf>
{
public Derived(DerivedConf DC) : base(DC)
{
}
public void PrintName()
{
Console.WriteLine(Conf.Name);
}
}
static void Main(string[] args)
{
var derived = new Derived(new DerivedConf("Foo"));
derived.PrintName(); // Foo
}
Here is my generic method from which i want to return the class object
public class TestBase
{
public T NavigateandReturntheObject<T>() where T : new()
{
//do navigate to page stuff and return the page object
//previously it was - return new T();
//Now i want to do something like this
return PageObjectBase<T>.PageObject;
}
}
Above method calling the below static generic class which will handle object creation of a particular class
public static class PageObjectBase<T> where T : class, new()
{
private static T singleTonObject;
public static T PageObject
{
get
{
return InstanceCreation();
}
}
public static T InstanceCreation()
{
if (singleTonObject == null)
{
singleTonObject = new T();
}
return singleTonObject;
}
}
How can i call the PageObject property from my test base class please advice.
Note : I have searched forum and find answers relevant to generic method to another generic method calling.The same is achieved by reflection.Can we use reflection in my case too? If so how can we do it.
You can add another constraint 'class' to NavigateandReturntheObject
public T NavigateandReturntheObject<T>() where T : class,new()
Complete Code.
public class TestBase
{
public T NavigateandReturntheObject<T>() where T : class,new()
{
//do navigate to page stuff and return the page object
//previously it was - return new T();
//Now i want to do something like this
return PageObjectBase<T>.PageObject;
}
}
Demo Code
public class TestClass
{
public string Name{get;set;}
public TestClass()
{
Name = "Dummy Name";
}
}
var testBase = new TestBase();
var sample = testBase.NavigateandReturntheObject<TestClass>();
Console.WriteLine(sample.Name);
Output
Dummy Name
Why doesn't the line marked with //Dont work in the bottom of the code compile?
I want to reuse the WriteMessage method with different Classes, I try to use generics, but I'm not sure how to use it.
class ClassOne
{
public string MethodOne()
{
return ("ClassOne");
}
public string MethodTwo()
{
return ("ClassOne -MethodTwo ");
}
}
class ClassTwo
{
public string MethodOne()
{
return ("ClassTwo");
}
public string MethodTwo()
{
return ("ClassOne -MethodTwo ");
}
}
class Program
{
private static void Main()
{
var objectOne = new ClassOne();
WriteMessage(objectOne);
var objectTwo = new ClassTwo();
WriteMessage(objectTwo);
Console.ReadKey();
}
public static void WriteMessage<T>(T objectA)
{
var text = objectA.MethodTwo(); //Dont Work
Console.WriteLine("Text:{0}", text);
}
}
Try implementing a interface :
Example :
public interface IHasTwoMethods
{
string MethodOne()
string MethodTwo()
}
Implement this inteface on your classes :
class ClassOne : IHasTwoMethods
class ClassTwo : IHasTwoMethods
Then in your generic method do like this :
public static void WriteMessage<T>(T objectA) where T : IHasTwoMethods
{
var text = objectA.MethodTwo(); //Will work
Console.WriteLine("Text:{0}", text);
}
You can read more about interfaces here : http://msdn.microsoft.com/en-us/library/87d83y5b.aspx
This doesn't compile because as far as the compiler is concerned objectA is just an Object.
To get this to work, you need to use a generic type constraint:
public interface MyInterface
{
string MethodTwo();
}
public class A : MyInterface
{
...
}
public class B : MyInterface
{
...
}
public static void WriteMessage<T>(T objectA) where T: MyInterface
{
var text = objectA.MethodTwo(); //Will Work!
Console.WriteLine("Text:{0}", text);
}
MSDN : Constraints on Type Parameters
Since you're passing in a generically-typed object with T, the compiler doesn't know what class you're using--for all it knows, it could be an int or an Application or anything.
What you probably want is to have ClassOne and ClassTwo inherit from another class that has an abstract MethodTwo class that both implement. Something like...
abstract class SuperClass
{
public abstract string MethodOne();
}
class ClassOne : SuperClass
{
public override string MethodOne()
{
return ("ClassOne");
}
}
then in Main:
public static void WriteMessage<T>(T objectA) where T : SuperClass
{
var text = objectA.MethodOne();
Console.WriteLine("Text:{0}", text);
}
Read up on C# inheritance here: http://msdn.microsoft.com/en-us/library/ms173149.aspx
This is what I want to do in C# (within class Helper - without generic arguments),
List<AbstractClass<dynamic>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<dynamic>) thing);
}
This helper class would take and work with AbstractClass<> objects and give back AbstractClass<> of specific generic type. AbstractClass<T> contains many functions which return T / take in T like public T Invoke().
For Helper class T cannot be known beforehand. The Add<T>(.. thing) function is not in a class of type T.
To be used like this in Helper class's functions,
foreach(var c in data.Where(x => ...))
{
// public T Invoke() { ... } function within AbstractClass<T>
var b = c.Invoke();
// logic
}
This also fails,
List<AbstractClass<object>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<object>) thing);
}
Now I think I can have,
List<dynamic> data; // or List<object> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add(thing);
}
but I want the constraint that List named data has only elements of type like
ConcreteClass : AbstractClass<OtherClass>
So we would know that there is an public T Invoke() function but we do not know what it returns. This is helpful to avoid mistakes of say misspelling Invocke and only knowing at run-time.
I want to avoid casting to dynamic every time to invoke functions that give back generic type T
To do what you want to do you are going to need to use a Contravariant interface
public class Program
{
static void Main()
{
var m = new Helper();
m.Add(new ConcreteClass());
m.Process();
}
class Helper
{
List<IAbstractClass<OtherClassBase>> data = new List<IAbstractClass<OtherClassBase>>();
public void Add(IAbstractClass<OtherClassBase> thing)
{
this.data.Add(thing);
}
public void Process()
{
foreach(var c in data.Where(x => x.ShouldBeProcessed()))
{
var b = c.Invoke();
Console.WriteLine(b.Question);
var castData = b as OtherClass;
if (castData != null)
Console.WriteLine(castData.Answer);
}
}
}
public interface IAbstractClass<out T>
{
bool ShouldBeProcessed();
T Invoke();
}
abstract class AbstractClass<T> : IAbstractClass<T>
{
public bool ShouldBeProcessed()
{
return true;
}
public abstract T Invoke();
}
class ConcreteClass : AbstractClass<OtherClass>
{
public override OtherClass Invoke()
{
return new OtherClass();
}
}
class OtherClassBase
{
public string Question { get { return "What is the answer to life, universe, and everything?"; } }
}
class OtherClass : OtherClassBase
{
public int Answer { get { return 42; } }
}
}
You do not need to tell Add what kind of class you are passing it, all that matters is it derives from the type specified. You could do public void Add(IAbstractClass<object> thing) and every class would work, but Invoke() would only return objects inside the foreach loop.
You need to figure out what is the most derived class you want Invoke() to return and that is what you set as the type in the list.
Maybe this will work for you:
public class Program
{
static void Main()
{
var m1 = new Helper<OtherClass>();
m1.Add(new ConcreteClass());
var m2 = new Helper<int>();
m2.Add(new ConcreteClass2());
}
class Helper<T>
{
List<AbstractClass<T>> data = new List<AbstractClass<T>>();
public void Add<T1>(T1 thing) where T1 : AbstractClass<T>
{
this.data.Add(thing);
}
}
class AbstractClass<T> { }
class OtherClass { }
class ConcreteClass : AbstractClass<OtherClass> { }
class ConcreteClass2 : AbstractClass<int> { }
}
I need to have a wrapper class that exposes some properties of my entity class called ProfileEntity.
I tried doing it by deriving from this entity and then creating properties that return specific entity properties, but it says I cannot cast from ProfileEntity to ProfileEntityWrapper.
When I try to put the return values of a method that returns a 'ProfileEntity' into the wrapper I get the above error.
How do I create such a wrapper class that is castable?
Example
class ProfileEntityWrapper : ProfileEntity
{
public string Name
{
get
{
return this.ProfileEntityName;
}
}
}
public class Someclass
{
public ProfileEntity SomeMethod()
{
return ProfileEntity; // example of method returning this object
}
}
public class SomeOtherlClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
ProfileEntityWrapper ew = (ProfileEntityWrapper)sc.SomeMethod(); // Cannot do this cast!!!
}
}
You cannot cast an object of ProfileEntity to ProfileEntityWrapper.
var entity = new ProfileEntity(); // this object is only of type ProfileEntity
var wrapper = new ProfileEntityWrapper(); // this object can be used as both ProfileEntityWrapper and ProfileEntity
You probably want to return a ProfileEntityWrapper in SomeMethod():
public class Someclass
{
public ProfileEntity SomeMethod()
{
return new ProfileEntityWrapper(); // it's legal to return a ProfileEntity
}
}
No, that is not possible.
To accomplish this problem you can maybe try this one:
public class ProfileEntity
{
public string ProfileEntityName { get; set; }
}
public class ProfileEntityWrapper
{
public ProfileEntityWrapper(ProfileEntity entity)
{
Entity = entity;
}
public ProfileEntity Entity { get; private set; }
public string Name
{
get
{
return Entity.ProfileEntityName;
}
}
}
public class SomeClass
{
public ProfileEntity SomeMethod()
{
// example of method returning this object
ProfileEntity temp = new ProfileEntity();
return temp;
}
}
public class SomeOtherClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
//Create a new Wrapper for an existing Entity
ProfileEntityWrapper ew = new ProfileEntityWrapper(sc.SomeMethod());
}
}
If you are allowed to edit the ProfileEntity class, or if the ProfileEntity class is a generated partial class, you could add an interface instead of using a wrapper. You wouldn't need to do any casting with an interface either. Example:
public interface IProfile
{
string Name { get; }
}
public partial class ProfileEntity : IProfile
{
public string Name
{
get
{
return this.ProfileEntityName;
}
}
}
public class SomeClass
{
public ProfileEntity SomeMethod()
{
return ProfileEntity;
}
}
public class SomeOtherClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
IProfile ew = sc.SomeMethod();
}
}
The IProfile instance will only provide access to the Name property.
This's no correct code from polymorphism aspect.
If we will take the famous polymorphism example when there're base Shape class and Circle, Polygon and Rectangle classes that extend the Shape class, your code will try to cast some shape into circle and as you understand this's invalid casting operation.
So to make this code work you must be sure that SomeClass.SomeMethod() will return instance of ProfileEntityWrapper or perform type check before the casting, like this:
ProfileEntity temp = sc.SomeMethod();
if(temp is ProfileEntityWrapper)
ProfileEntityWrapper ew = (ProfileEntityWrapper) temp;