If I have a class B and C which inherits from A, is there something simpler than using StackFrame's GetFileName() (then parse out the ClassName.cs string)?
If I use this.GetType().Name, it won't return "A" when the code is executing in the parent class.
Sample Code
namespace StackOverflow.Demos
{
class Program
{
public static void Main(string[] args)
{
B myClass = new C();
string containingClassName = myClass.GetContainingClassName();
Console.WriteLine(containingClassName); //should output StackOverflow.Demos.B
Console.ReadKey();
}
}
public class A { public A() { } }
public class B : A { public B() { } }
public class C : B { public C() { } }
}
var yourType = GetType();
var baseType = yourType.BaseType;
or alternatively:
var currentTypeName = new StackFrame(1, false).GetMethod().DeclaringType.Name;
I use myObject.GetType().FullName which returns the fully qualified name of the class. For your scenario, you could use myObject.GetType().BaseType.FullName
Option 1 :: Getting the "container" class:
/**CODE**/
public static void Main(string[] args)
{
B c = new C();
Test(c);
Console.ReadKey();
}
public static void Test(A a) { Console.WriteLine(typeof(A).ToString()); }
public static void Test(B b) { Console.WriteLine(typeof(B).ToString()); }
public static void Test(C c) { Console.WriteLine(typeof(C).ToString()); }
/**OUTPUT**/
StackOverflow.Demos.B
Option 2 :: Getting the "container" class:
/**CODE**/
class Program
{
public static void Main(string[] args)
{
B myClass = new C();
Console.WriteLine(myClass.GetContainerType()); //should output StackOverflow.Demos.B
Console.ReadKey();
}
}
public interface IGetContainerType
{
Type GetContainerType();
}
public class A: IGetContainerType
{
public A() { }
public Type GetContainerType()
{
return typeof(A);
}
}
public class B : A
{
public B() { }
public new Type GetContainerType()
{
return typeof(B);
}
}
public class C : B
{
public C() { }
public new Type GetContainerType()
{
return typeof(C);
}
}
/**OUTPUT**/
StackOverflow.Demos.B
Answer to similar but different question; Getting the instance class / full hierarchy:
/**CODE**/
class Program
{
public static void Main(string[] args)
{
C c = new C();
Type myType = c.GetType();
while(myType != null)
{
Console.WriteLine(myType);
myType = myType.BaseType;
}
Console.ReadKey();
}
}
/**OUTPUT**/
StackOverflow.Demos.C
StackOverflow.Demos.B
StackOverflow.Demos.A
System.Object
When you say GetType(), or equivalently this.GetType(), you get the actual type of the class. For example
class A
{
public void Test()
{
Console.WriteLine(GetType().Name);
}
}
class B : A
{
}
and later:
var myB = new B();
myB.Test(); // writes B to the console
I guess that's what polymorphism is all about.
If you want always A, no polymorphism, simply say:
class A
{
public void Test()
{
Console.WriteLine(typeof(A).Name);
}
}
class B : A
{
}
Related
I am creating one console application. I have one class in which I wrote some methods. Now I want to override some methods of that class in a different class. But this should be override only if condition satisfied.
For example,
public partial Class MainClass
{
public string GetPath()
{
string temp = Method1();
return temp;
}
protected virtual string Method1()
{
//logic
}
}
If some condition satisfied then only overridden method should be called
public partial class ChildClass : MainCLass
{
public override void Method1()
{
//MY Logic
}
}
How can I achieve this? Is it possible to do so?
In ChildClass you can do something like this:
public partial class ChildClass : MainCLass
{
public override void Method1()
{
if(condition)
{
base.Method1();
return;
}
//YOUR LOGIC
}
}
EXAMPLE
public class A
{
public virtual void MethodA()
{
Console.WriteLine("A:MethodA");
}
}
public class B : A
{
public bool CallBase { get; set; }
public B()
{
CallBase = false;
}
public override void MethodA()
{
if (CallBase)
{
base.MethodA();
return;;
}
Console.WriteLine("B:MethodA");
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
a.MethodA();
b.MethodA();
b.CallBase = true;
b.MethodA();
A c = new B();
c.MethodA();
A d = new B(true);
d.MethodA();
Console.ReadKey();
}
}
Output
A:MethodA
B:MethodA
A:MethodA
B:MethodA
A:MethodA
I have a requirement of dynamically invoke a class and use the methods of that class.
public class A
{
public void test()
{
}
}
public Class B
{
public void test()
{
}
}
class object intermediate
{
//here will decide which class to be invoked
//return the invoked class instance
}
class clientclass
{
intermedidate client=new intermediate();
}
So can i access the methods of the invoked class, in the instance client.
Im using Framework 3.5. If child class inherited from the intermediate class, is it possible to achieve this? I dont want reflection here.
You can do like follows (not verified)
interface I
{
}
class A :I
{
}
Class B:I
{
}
class intermediate
{
public I GetInstance(int i)
{
if(i==1)
return new A();
else
return new B();
}
}
class clientclass
{
I client=new intermediate().GetInstance(1);
}
Try this
public interface IClassA
{
void Method();
}
public class ClassA : IClassA
{
public void Method()
{
}
}
public static class ObjectInjector
{
public static T GetObject<T>()
{
object objReturn = null;
if(typeof(T) == typeof(IClassA))
{
objReturn = new ClassA();
}
return (T)objReturn;
}
}
public class ClientClass
{
static void Main(string[] args)
{
IClassA objA = ObjectInjector.GetObject<IClassA>();
objA.Method();
}
}
You could try and do the interface implementation as the Șhȇkhaṝ has above.
You could also use an abstract class if you require initial processing before class A or B's test method is invoked.
Here is an example of a console app that demonstrates this:
public abstract class MainClass
{
public virtual void test()
{
Console.WriteLine("This is the abstract class");
}
}
public class A : MainClass
{
public override void test()
{
base.test();
Console.WriteLine("Class A");
}
}
public class B : MainClass
{
public override void test()
{
base.test();
Console.WriteLine("Class B");
}
}
public class Intermediate
{
public MainClass CreateInstance(string name)
{
if (name.ToUpper() == "A")
{
return new A();
}
else
{
return new B();
};
}
}
class Program
{
static void Main(string[] args)
{
Intermediate intermediate = new Intermediate();
var client = intermediate.CreateInstance("B");
client.test();
Console.ReadLine();
}
}
Is there a way we can access the concrete method's of an abstract class in the direct child class as below
abstract class ParameterBase
{
public void test()
{
string name = "testname";
console.writeline(name);
}
}
public class Parameter1 : ParameterBase
{
//I Need to call(access) the Test() Method here i.e print "testname" in the console
}
Now i know that we can create a instance of the child class with type as ParameterBase and access the test() method that is there in ParameterBase() as below
ParameterBase PB = new Parameter1();
PB.test();
You have to maintain the accessibility level while inheriting a class. You can do this :
abstract class ParameterBase
{
public void test()
{
string name = "testname";
Console.WriteLine(name);
}
}
class Parameter1 : ParameterBase
{
void getvalue()
{
Parameter1 pb = new Parameter1();
pb.test();
}
}
Please look into this:-
class Program
{
static void Main(string[] args)
{
Test2 t = new Test2();
t.display();
t.absDsisplay();
}
}
abstract class Test1
{
public void display()
{
Console.WriteLine("display");
}
public abstract void absDsisplay();
}
class Test2 : Test1
{
void GetValu()
{
}
public override void absDsisplay()
{
Console.WriteLine("absDisplay");
}
}
You can do this
class Program
{
static void Main(string[] args)
{
Parameter1 parameter1 = new Parameter1();
parameter1.te();
Console.ReadLine();
}
}
public abstract class ParameterBase
{
public void test()
{
string name = "testname";
Console.WriteLine(name);
}
}
public class Parameter1 : ParameterBase
{
public void te()
{
test();
}
//I Need to call(access) the Test() Method here i.e print "testname" in the console
}
I'm working to DRY some code up and I'm running into the following situation. I've reworked the code to provide a better example of the scenario.
namespace SourceCode
{
public interface IFactory
{
public baseClass GenerateClass();
public bool IsUsable();
}
public abstract baseClass
{
...
}
public AClass:baseClass
{
...
}
public class FactoryA:IFactory
{
public baseClass GenerateClass()
{
return new AClass();
}
public bool IsUsable(){
{
return true if some condition;
}
}
public BClass:baseClass
{
...
}
public class FactoryB:IFactory
{
public baseClass GenerateClass()
{
return new BClass();
}
public bool IsUsable(){
{
return true if some condition;
}
}
public static class FactoryProvider
{
List<IFactory> factories
static FactoryProvider()
{
factories.Add(new FactoryA());
factories.Add(new FactoryB());
}
static List<baseClass> GetClasses()
{
return (from f in factories where f.IsUsable() select f).ToList();
}
}
}
namespace SourceCode.Tests
{
public class baseTests
{
public T GenericMethod<T>(){...}
}
public class ClassATests:baseTests
{
public void Test1()
{
... generic used in a method provided by the base class
}
}
public class ClassBTests:baseTests
{
public void Test1()
{
... generic used in a method provided by the base class
}
}
}
So the problem in my tests is that there are tests that will have to happen for every child class.
UPDATE=======================
I was able to solve my issue by doing the following.
namespace SourceCode.Tests
{
public class baseTests<I> where I: baseClass
{
public void Test1()
{
var result = GenericMethod<I>();
// The generic method will use ClassA for ClassATests
// and ClassB for ClassBTests
}
public T GenericMethod<T>(){...}
}
public class ClassATests:baseTests<ClassA>
{
}
public class ClassBTests:baseTests<ClassB>
{
}
}
Making your current A class generic could solve problems:
abstract class A
{
// protected members...
protected abstract A InternalGetData(List<A> src);
public void SharedMethodHappensAlways()
{
List<A> src = new List<A>();
var childResult = InternalGetData(src);
}
}
abstract class A<T> : A
where T: A
{
public T GetData(List<A> src)
{
return src.OfType<T>().FirstOrDefault();
}
protected override A InternalGetData(List<A> src)
{
return GetData(src);
}
}
class B : A<B>
{
}
class C : A<C>
{
}
Sample usage:
List<A> src = new List<A>() { new B(), new C() };
B b = new B();
b.SharedMethodHappensAlways();
B firstB = b.GetData(src); // returns first instance of B
C firstC = new C().GetData(src);
So I only want to use one class Object for all of my functions but I do not want to directly use that class instead I need to access the members of the derived classes.
Take this example:
class A {
public A() {
}
public void DoSomething() { }
}
class B : A {
public B() {
}
public void DoSomethingBetter() { }
}
class C : A {
public C() {
}
public void DoSomethingBest() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
objB.DoSomethingBetter(); //Won't compile
A objC = new C();
objC.DoSomethingBest(); //Won't compile
}
}
I don't want to initialize them as B objB = new B(), that is not the purpose and I already know that that could be a solution. I need to just use the parent class for this.
Thanks
If you're going to declare the methods with different names, you're going to have to instantiate the explicit type in your code.
If the methods all perform the same function but in different manners, you should override the method from the base class rather than re-implement it with a different name.
public class A
{
public virtual void DoSomething()
{
// some implementation
}
}
public class B : A
{
public override void DoSomething()
{
// body of DoSomethingBetter
}
}
public class C : A
{
public override void DoSomething()
{
// body of DomSomethingBest
}
}
The body of your application would simplify to:
A b = new B();
A c = new C();
b.DoSomething() // uses logic of DoSomethingBetter
c.DoSomething() // uses logic of DoSomethingBest
Not 100% sure what you're trying to accomplish, but this is an option if for some reason you don't want to override as others suggested.
class A {
public A() {
}
public void DoSomething() { }
}
class B : A {
public B() {
}
public void DoSomethingBetter() { }
}
class C : A {
public C() {
}
public void DoSomethingBest() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
if (objB is B)
((B)objB).DoSomethingBetter();
A objC = new C();
if (objC is C)
((C)objC).DoSomethingBest();
}
}
EDIT: A more efficient way to do this is as follows (it will run 2 casts instead of 4):
class A {
public A() {
}
public void DoSomething() { }
}
class B : A {
public B() {
}
public void DoSomethingBetter() { }
}
class C : A {
public C() {
}
public void DoSomethingBest() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
B objAB = objB as B;
if (objAB != null)
objAB.DoSomethingBetter();
A objC = new C();
C objAC = objC AS C;
if (objAC != null)
objAC.DoSomethingBest();
}
}
Is it perhaps overriding that you are looking for?
You can make the A class abstract, and methods in it also. Then put the actual implementation in the derived classes:
abstract class A {
public A() {
}
public abstract void DoSomething() { }
}
class B : A {
public B() {
}
public override void DoSomething() { }
}
class C : A {
public C() {
}
public override void DoSomething() { }
}
class Runner {
public static void Main(String[] args) {
A objB = new B();
objB.DoSomething(); // Uses the B implementation
A objC = new C();
objC.DoSomething(); // Uses the C implementation
}
}
Without seeing your actual code I'm inclined to agree with everyone else who says you should really try again to fix your problem using simple overrides.
Nevertheless, I had some fun toying around with this problem and managed to write a solution that does no casting.
Enjoy!
public class BattlePlan
{
public Action<Puppy> ExecutePuppyAttack { get; set; }
public Action<Pigeon> ExecutePigeonAttack { get; set; }
}
public abstract class Animal
{
public abstract void Attack(BattlePlan battlePlan);
}
public class Puppy : Animal
{
public void Bite(bool barkFirst)
{
// optionally bark at the intruder,
// then bite as deeply as needed.
}
public override void Attack(BattlePlan battlePlan)
{
battlePlan.ExecutePuppyAttack(this);
}
}
public class Pigeon : Animal
{
public void Bombard(int altitude)
{
// ewww. nuff said.
}
public override void Attack(BattlePlan battlePlan)
{
battlePlan.ExecutePigeonAttack(this);
}
}
public class EvilMasterMind
{
private bool _puppiesMustBark = true;
private int _pigeonAltitude = 100;
public void Attack()
{
var battlePlan = new BattlePlan
{
ExecutePuppyAttack = e => e.Bite(_puppiesMustBark),
ExecutePigeonAttack = e => e.Bombard(_pigeonAltitude)
};
var animals = new List<Animal>
{
new Puppy(),
new Pigeon()
};
foreach (var animal in animals)
{
animal.Attack(battlePlan);
}
}
}