C# generics type interference strange behaviour - c#

Consider the following code :
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
Print(a);
Print(b);
Console.WriteLine(b.Hello);
Console.ReadLine();
}
static void Print<T>(T t) where T : A
{
Console.WriteLine(typeof(T));
Console.WriteLine(t.GetType());
Console.WriteLine(t.Hello);
}
}
public class A
{
public string Hello { get { return "HelloA"; } }
}
public class B : A
{
public new string Hello { get { return "HelloB"; } }
}
The output I got (.NET FW 4.5)
//Print(a)
A
A
HelloA
//Print(b)
B
B
HelloA
//Explicit Writeline
HelloB
Can anyone explain how I got the 2nd HelloA, as I was expecting HelloB ?

public new string Hello { get { return "HelloB"; } }
The new keyword creates a new function which just happens to have the same name as the old one. Thus, B now has two methods: Hello (A), which is executed when invoked through a variable of compile-time type A, and Hello (B), which is executed when invoked through a variable of compile-time type B (or a subtype thereof).
Since your generic parameter is T : A, the compiler compiles t.Hello as a call to Hello (A).
B shadows (or hides) method Hello rather than overriding it.
What you probably wanted to write was:
public class A
{
public virtual string Hello { get { return "HelloA"; } }
}
public class B : A
{
public override string Hello { get { return "HelloB"; } }
}
Note that the base method is declared as virtual, and the subclass method as override.

Related

generic method access hidden property in c#

I'm currently having trouble and I have no clue how to fix it.
I have 2 classes:
class A
{
public string MyParam { get; set; }
}
class B : A
{
public new string MyParam { get { return base.MyParam != null ? base.MyParam.Substring(1) : null; } }
}
When I try to access the B.MyParam it works when I have a the correct type, but in most of my methods I have a generic type
with :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
public class A
{
public string MyParam { get; set; }
}
public class B : A
{
public new string MyParam
{
get { return base.MyParam != null ? base.MyParam.Substring(1) : null; }
}
}
public static void MyMethod<T>(T variable) where T : A
{
Console.WriteLine(variable.MyParam);//this print hello
Console.WriteLine((variable as B).MyParam);//this print ello (exactly what i want)
Console.WriteLine(typeof(T)); // this print ConsoleApplication1.Program+A
Console.WriteLine(variable.GetType()); // this print ConsoleApplication1.Program+B
// so i need something like that
Console.WriteLine((variable as variable.GetType()).MyParam); // this line is invalid
}
static void Main(string[] args)
{
A a = new B();
a.MyParam = "Hello";
Console.WriteLine(a.GetType());
MyMethod(a);
Console.ReadKey();
}
}
}
Is there a way to do it?
Thank you in advance.
EDIT: it seems that what i want is :
dynamic variable2 = Convert.ChangeType(variable, variable.GetType());
Console.WriteLine(variable2.MyParam);
Your code doesn´t make any sense. If A inherits from B you´ll need A to override the base-implementation for your property. So I´ll assume you should rethink your inheritance-chain.
You can use override for this. Thus when your variable-parameter is of your base-class (I renamed that to A) you´re calling the base-method, if it´s a derived instance (here B) you´re calling the override:
class A
{
public virtual string MyParam { get; }
}
class B : A // note here that B derives from A, not the other way round
{
public override string MyParam
{
get { return base.MyParam != null ? base.MyParam.Substring(1) : null; },
set { ... }
}
}
EDIT: While new intrduces a new member which (accidentally) has the same name (and signature) as the base-member it effectivly hides the base-member. Thus you effectivly have two members. Your only way to indicate which member should be used is by casting your instance to the desired class from which you need the implementation. However this somehow breaks the purpose of generics as the generic member has to know the exact types that are possible for the type-parameter.
Anyway this seems like broken design to me, as you´re actually creating a new member which has another meaning. So you should also give it a new name.
Based on your generic method, I think all you need is an interface.
public interface IMyParam
{
string MyParam { get; set; }
}
Your classes.
class A : IMyParam
{
public virtual string MyParam { get; set; }
}
class B : A
{
public override string MyParam
{
get { return base.MyParam != null ? base.MyParam.Substring(1) : null; }
}
}
And your method, won't need to be generic.
public void MyMethod(IMyParam variable)
{
// Your logic here, for example.
Console.WriteLine(variable.MyParam);
}
Calling your method.
A a = new A();
a.MyParam = "Hello";
B b = new B();
b.MyParam = "Hello";
A ab = new B();
ab.MyParam = "Hello";
MyMethod(a); // Prints Hello
MyMethod(b); // Prints ello
MyMethod(ab); // Prints ello

Single instance without singleton pattern

Kindly suggest me the best pattern which will suits the below need.
Class Base
{
List<string> a;
List<string> b;
public Base()
{
//"Calling Base"
}
}
Class Der : Base
{
GetListA()
{
return a;
}
GetListB()
{
return b;
}
}
Class Der1 : Base
{
GetListA()
{
return a;
}
GetListB()
{
return b;
}
}
Main()
{
Der1 obj1 = new Der1();
Der obj= new Der();
obj.GetListA();
obj.GetListB();
obj1.GetListA();
obj1.GetListB();
}
when I use obj1 or obj2, currently the base class constructor is getting called every time a new object is created.
Base class is generating say 10k records. I want that to be generated only once and keep it for others to reuse it.
Its purely web server application and my application wont accept any static variables/object or singleton class. Without that I need to perform this task.
Is there any way to achieve this??
Class Base
{
static List<string> a;
static List<string> b;
public Base()
{
if(this.a == null)
{
a = database.GetListitemsForA();
}
if(this.b == null)
{
b = database.GetListitemsForB();
}
}
}
Something similar to using a static variable is to use the Application property
You could use a property like this to void creating multiple instances of your class
public SomeClass Instance
{
get
{
if (Application["SomeClassInstance"] == null)
{
Application["SomeClassInstance"] = new SomeClass();
}
return (SomeClass)Application["SomeClassInstance"];
}
}

How to know the calling Class Name?

Is there a way know which class has called a function in another class.
Eg:
public class A
{
public static string Aa = "test";
public void test()
{
B.testB();
}
}
public class B
{
public static void testB()
{
string Bb = A.Aa;
}
}
In the above example, i know the class A function has called the function in class B. But if there are many classes which will call the function in class B and all of those classes will have variable Aa in common, so how can i read its value and assign it to Bb. So in simple
string Bb = CalledClassName.Aa;
You could use the CallerMemberNameAttribute that was added with .NET 4.5. This will only get you the member name though:
public void SomeMethod ()
{
OtherMethod();
}
public void OtherMethod ([CallerMemberName] string memberName = null)
{
Console.WriteLine(memberName);
}
The attribute will fill the optional parameter at compile time, so it will actually call OtherMethod("SomeMethod").
You could also use a combination of accessing the stack trace and using reflection to read the Aa property of the type of the calling method. Note that this accesses debugging information, and is very vulnerable to changes in your code. It also has a bad performance, so you should avoid it. But just to show you how to use it:
public static void testB()
{
StackTrace stackTrace = new StackTrace();
Type callingType = stackTrace.GetFrame(1).GetMethod().DeclaringType;
FieldInfo field = callingType.GetField("Aa", BindingFlags.Public | BindingFlags.Static);
string Bb = (string) field.GetValue(null);
Console.WriteLine(Bb);
}
Use an interface, pass that in:
public interface AaInterface {
public string GetAa();
}
public class A : AaInterface
{
public static string Aa = "test";
public GetAa() { return Aa; }
public void test()
{
B.testB(this);
}
}
public class B
{
public static void testB(AaInterface pAa)
{
string Bb = pAa.GetAa();
}
}
I guess you are looking for something different than you are asking.
You should pass the instance of A to your method. All calling methods should pass the instance based on an interface. In that interface you put the properties and methods you want to share. In that way you can call the 'same' method for every passed instance.
public interface ISomeInterface
{
string Aa {get;}
}
public class A : ISomeInterface
{
public string Aa {get { return "a"; } }
}
Then you can pass it to this method:
public static void testB(ISomeInterface something)
{
string Bb = something.Aa;
}
Note that in this case, Aa is not allowed to be static. You could wrap that static in an instance property though.
If i understood your question correctly then you can pass a reference to a class instance in method as parameter then use 'is' operator to check its type:
public class A
{
public static string Aa = "test";
public void test(object calledClass)
{
if(calledClass is B) Aa = calledClass.Bb;
}
}
When you call this static method from class B just put :
A.Test(this)
P.S.
This is just an example of logic that you can use to achieve what you want
I geuss you can do something like this:
public class A {
public void test() {
B.testB(this);
}
}
public class B {
public static void testB(object sender) {
String className = sender.GetType().Name;
}
}
//To call
A a = new A();
a.test();

Cloning a method in c#

Suppose I have a class A:
class A
{
void b() {...}
}
and a class B:
class B
{
A m;
}
This way, if I write B x, I can call x.m.b().
What I need is to dynamically create a method b() inside the B class, so I could use it as x.b() (of course, the results from calls x.m.b() and x.b() should be the same).
How can I do it?
There is one generic solution (where you won't have to f.e create delegates for every method from A you want). Unfortunately, It won't be a strongly-typed one. If you want so, please see other answers.
class A
{
public int B()
{
return 1;
}
}
class B : DynamicObject
{
private readonly A m = new A();
private static readonly Lazy<IEnumerable<MethodInfo>> AMethods =
new Lazy<IEnumerable<MethodInfo>>(() =>
{
var type = typeof (A);
return type.GetMethods(
BindingFlags.Instance |
BindingFlags.Public);
});
public override bool TryInvokeMember(
InvokeMemberBinder binder,
object[] args,
out object result)
{
if (base.TryInvokeMember(binder, args, out result))
{
return true;
}
var methods = AMethods.Value;
var method = methods.SingleOrDefault(mth => mth.Name == binder.Name);
// TODO: additional match (arguments type to handle overloads)
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(this.m, args);
return true;
}
public int OtherBMethods()
{
return 2;
}
}
Usage:
var b = new B();
int result = ((dynamic)b).B();
int other = b.OtherBMethods();
or
dynamic b = new B();
int result = b.B();
int other = b.OtherBMethods();
You could do this with delegates, in modern C# this could look like this
public class A
{
public void b() {...}
}
public class B
{
private A m = new A();
public Action b = ()=>m.b();
}
public void Main()
{
new B().b(); // This now invokes your delegates that invokes the b method on it's internal m object
}
Could also just do it with classical methods and simply expose a b method that does the exact same thing, don't see anything special / hard here? If you're trying to accomplish something else you need to clarify your question, like if you want to automate this there are easy compile time (T4 text templates) or at runtime (generating dynamic proxies).
What you are going to do is implement Decorator pattern in C#.
GoF defines Decorator pattern as "Attach additional responsibilities
to an object dynamically. Decorators provide a flexible alternative to
subclassing for extending functionality.
I would like to recommend look throught this article "Understanding and Implementing Decorator Pattern in C#".
I have created a simple example of the Decorator pattern implementation when you decorate Concrete with A and B functionality.
interface IDecorator
{
void Print();
}
class Concrete : IDecorator
{
public void Print()
{
Console.WriteLine("-> Concrete");
}
}
class A : IDecorator
{
IDecorator decorator;
public A(IDecorator decorator)
{
this.decorator = decorator;
}
public void Print()
{
decorator.Print();
Console.WriteLine("-> A");
}
}
class B : IDecorator
{
IDecorator decorator;
public B(IDecorator decorator)
{
this.decorator = decorator;
}
public void Print()
{
decorator.Print();
Console.WriteLine("-> B");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("concrete object that should be decorated");
var concrete = new Concrete();
concrete.Print();
Console.WriteLine("let's decorate this object with A decorator");
var decoratedWithA = new A(concrete);
decoratedWithA.Print();
Console.WriteLine("let's decorate this object with B decorator");
var decoratedWithB = new B(concrete);
decoratedWithB.Print();
Console.WriteLine("let's decorate concrete with A and B");
var decoratedWithAB = new B(new A(concrete));
decoratedWithAB.Print();
}
}
I have an abstract A class and classes A1 : A, A2 : A, A3 : A. Then i
also have a method named c(). I want to create classes
A1_with_c_method, A2_with_c_method, A3_with_c_methos while leaving A1,
A2 and A3 unharmed. What is the best way to do this? – h8red
You could do something like this:
abstract class A
{
}
class A1 : A
{
}
class A2 : A
{
}
class A3 : A
{
}
#region Not a good idea, because too many classes
class A1_with_c : A1
{
public void c() { }
}
class A2_with_c : A2
{
public void c() { }
}
class A3_with_c : A3
{
public void c() { }
}
#endregion
// Decorate A with the c() method
class BaseDecorator
{
public A Instance { get; private set; }
public BaseDecorator(A instance)
{
Instance = instance;
}
public virtual void c()
{
// do something with instance
}
}
class Decorator : BaseDecorator
{
BaseDecorator decorator;
public Decorator(BaseDecorator decorator)
: base(decorator.Instance)
{
this.decorator = decorator;
}
public override void c()
{
Console.WriteLine("Ok");
}
}
class Program
{
static void Main(string[] args)
{
// not good
new A1_with_c().c();
new A2_with_c().c();
new A3_with_c().c();
// better
var a_with_c = new BaseDecorator(new A1());
a_with_c.c();
// Let's decorate with something interesting
new Decorator(a_with_c).c();
}
}
I agree with the comments that this really seems odd and I'm wondering why you would ever want to do this but here is a possibility for you.
interface IHasMethodb
{
void b();
}
class A : IHasMethodb
{
public void b() { ... }
}
class B : IHasMethodb
{
A m;
public void b() { return m.b(); }
}
Is this what you're trying to do?
It seems like you either want the concept of wrapping a method, which in your example is as simple as:
class A {
public void b() { ... }
}
class B {
A m;
public void b() { m.b(); }
}
Allowing you to:
B x = new B();
x.b();
If you want to be able to "dynamically create" the method then this might be more applicable, using an Action<T> to allow you to do whatever you like with the A instance, without actually exposing it:
class A {
public void b() {...}
}
class B {
A m;
public Action<A> doSomethingWithA;
public void b() {
if (doSomethingWithA != null)
doSomethingWithA(m);
}
}
Then you can:
B x = new B();
x.doSomethingWithA = a => a.b();
x.b();

C# cast generic T in abstract class<T> to dynamic

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> { }
}

Categories

Resources