Can i Do object reflection in C# - c#

I have two classes, Dog and Cat
class Dog
{
public void speak() {
System.out.println("Woof!");
}
}
class Cat
{
public void speak() {
System.out.print("Meow!");
}
}
In my main, I take the name as String, either "Cat", or "Dog".
public static void main(String [] args)
{
Scanner sc = new Scanner(System.in);
String name = sc.next();
Class<?> cls = Class.forName(name);
Object object = cls.newInstance();
}
Can i do this in C#??

Line by line it would be:
public static void Main(string[] args)
{
string name = Console.ReadLine();
// The second true will ignore case
var cls = Type.GetType("Animals." + name, true, true);
var #object = Activator.CreateInstance(cls);
}
with the various animals like:
namespace Animals
{
public class Dog
{
public void speak()
{
Console.WriteLine("Woof!");
}
}
public class Cat
{
public void speak()
{
Console.WriteLine("Meow!");
}
}
}
I've added a namespace to make it a "more complete" example: in .NET you can have your code *outside" any namespace, but normally you'll use a namespace. I'm prepending it to the name of the class obtained from the console ("Animals." + name).
Note that this code is quite useless, because without a base interface/class, you can't easily make them speak() (you can go full reflection/dynamic from this point onward to do it but it is "bad")
Bad way with dynanic:
dynamic #object = Activator.CreateInstance(cls);
#object.speak();
(note that I'm not supporting what you are doing, it is bad in multiple ways)

Related

How to set up method variables to class object properties/values

Simply put how do you establish a connection between method variable decloration and connect it with class properties (or inner objects), lets say you have default or hard set values in a class like this (obviously they could be other types but for simplicity its set to strings) :
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
//think of it as a data layer where strings are pointers to dbSets
How do you leverage the same SampleClass in a method that allows ONLY pick of properties Method(property).
Easy sample that does what its supposed to:
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(string input)
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
var Test = new ProccessClass().Pick(new SampleClass().strB);
// we know this works and compiles and returns the strB
}
}
What would you have to convert to ommit the new instantiation and skip the class declaration (if possible but in theory should be doable)
new SampleClass().strB
needs to be just
strB
So how to get the final code to execute??
public class SampleClass
{
public string strA = "Something 1";
public string strB = "Something 2";
public string strC = "Something 3";
}
public class ProccessClass
{
private string _dummyOut;
public ProccessClass Pick(SampleClass sampleClass) //is it the variable declaration?
{
this._dummyOut = input;
return this;
}
}
class Program
{
static void Main(string[] args)
{
string Test = new ProccessClass().Pick(strB);
//so NO new keywords clean and easy set based on class provided above
}
}
Constructor and void setters but no go, the goal is to set the Hard relation ship between the method intake value and setters

C# master class that calls other classes with similar properties

I have a lot of classes that store different types of data but manipulate the data differently. Is there someway I can abstract what class I'm using...and just call the class's methods? I will have one object that I'm using at a given moment, masterclass.
For example I have class1 and class2. Both classes can do .add .subtract...etc.
I want to say...masterclass is now class1. So I can do masterclass.add instead of class1.add. Then change masterclass to class2 and do a masterclass.subtract instead of class1.subtract.
Ok...maybe this is clearer:
class cat
{
String legs="4 legs";
String claws="cat has lots of claws";
public string GetLegs()
{ return legs+claws;
}
}
class bird
{
String legs="2 wings";
String talons="Bird has 2 talons";
public string GetLegs()
{ return legs+talons;
}
}
class animal;
mainfunction()
{
string temp;
animal = cat;
temp = animal.GetLegs();
animal = bird;
temp = animal.getLegs();
}
You could do it in several ways, either you use interfaces, and implement it like for example:
public interface ICalculate {
void Add();
void Subtract();
}
and implement your classes in such a way that they inherit from the interface, like so:
public class SpecificClass : ICalculate {
public void Add() {
// ...
}
public void Subtract() {
// ...
}
}
public class OtherSpecificClass : ICalculate {
public void Add() {
// ...
}
public void Subtract() {
// ...
}
}
or you can use an abstract base class like:
public abstract class AbstractCalculate {
public abstract void Add();
public abstract void Subtract();
}
and implement specific classes like:
public class SpecificCalculate : AbstractCalculate {
public override void Add() {
// ...
}
public override void Subtract() {
// ...
}
}
in the first example you can create your specific classes like:
ICalculate calc1 = new SpecificCalculate();
and call
calc1.Add();
in the second one one, you can use
AbstractCalculate calc11 = new SpecificCalculate();
and call
calc1.Add();
both have a similar way of working, both have their advantages
more info you can find for example on MSDN
Per suggestion of Ed Plunkett, you could have then for example following implementations (lets say for the ICalculate version)
IList<ICalculate> calculations = new List<ICalculate>();
// <-- add specific instances to the list
calculations.Add( new SpecificClass() );
calculations.Add( new OtherSpecificClass() );
// iterate the list
foreach (var calculation in calculations) {
calculation.Add();
}
or to be more specific to your updated question
public interface IAnimal {
int GetLegs();
}
public class Bird : IAnimal {
public int GetLegs() {
return 2;
}
}
public class Cat : IAnimal {
public int GetLegs() {
return 4;
}
}
and the program would use it like
class Program {
static int GetLegs(IAnimal animal) {
return animal.GetLegs();
}
static void Main(string[] args) {
Cat cat = new Cat();
Bird bird = new Bird();
Console.WriteLine( GetLegs( bird ) ); // 2
Console.WriteLine( GetLegs( cat ) ); // 4
}
}
Or like
IList<IAnimal> animals = new List<IAnimal>();
animals.Add( new Cat() );
animals.Add( new Bird() );
int totalLegs = 0;
foreach (var animal in animals) {
totalLegs += animal.GetLegs(); // or totalLegs += GetLegs( animal );
}
Console.WriteLine( totalLegs ); // 6

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();

Using methods on Generics

I have a ton of methods like this:
public UIPCompanyButton AddCompanyButton (string name, Company company, UIEventListener.VoidDelegate methodToCall, GameObject contents)
{
return UIPCompanyButton.Create (name, company, methodToCall, contents);
}
that I'd like to replace with a single method like this:
public T AddButton<T,K>(string name, K item, UIEventListener.VoidDelegate methodToCall, GameObject contents) where T:UIPMenuButton
{
return T.Create(name, item, methodToCall, contents);
}
which obviously doesn't work at the T.Create part. Is there a certain syntax I need to do this?
I'm also open to a different method with the same result: a single method that takes in a derived menuButton and creates the right one with the right class of "item".
No, you can't call static methods on generic types - not without reflection. Aside from anything else, there's no way of constraining a generic type to have specific static members. The closest to that is the parameterless constructor constraint.
What you want is a factory to create your objects. Here is a small working example. It might not be the best way to implement a factory pattern, but it should get you going.
For a more in depth example and explanation, see this page.
public class Button {
public string Whatever { get; set; }
public Button() {
Whatever = "Hello, world!";
}
}
public interface IAddButton {
Button CreateButton();
}
public class ClassToMakeButtonFor1 {
public static void RegisterMe() {
ButtonFactory.Register(typeof(ClassToMakeButtonFor1), new ButtonFactory1());
}
}
public class ButtonFactory1 : IAddButton {
public Button CreateButton() {
return new Button();
}
}
public class ClassToMakeButtonFor2 {
public static void RegisterMe() {
ButtonFactory.Register(typeof(ClassToMakeButtonFor2), new ButtonFactory2());
}
}
public class ButtonFactory2 : IAddButton {
public Button CreateButton() {
var b = new Button { Whatever = "Goodbye!" };
return b;
}
}
public static class ButtonFactory {
private static Dictionary<Type, IAddButton> FactoryMap = new Dictionary<Type, IAddButton>();
public static void Register(Type type, IAddButton factoryClass) {
FactoryMap[type] = factoryClass;
}
public static Button MakeMeAButton<T>() where T : class {
return FactoryMap[typeof(T)].CreateButton();
}
}
internal class Program {
private static void Main(string[] args) {
ClassToMakeButtonFor1.RegisterMe();
ClassToMakeButtonFor2.RegisterMe();
Button b = ButtonFactory.MakeMeAButton<ClassToMakeButtonFor1>();
Console.WriteLine(b.Whatever);
b = ButtonFactory.MakeMeAButton<ClassToMakeButtonFor2>();
Console.WriteLine(b.Whatever);
Console.ReadLine();
}
}
What you could consider is to have some interface (e.g. ICreator) that defines a Create method you want to call.
Then you would constrain your type parameter to types that implement the interface ( where T : ICreator).
Then you would call the method on an instance, not a static method. So in your case maybe you could call item.Create(...).
Makes any sense for your case?
It sounds like you might be able to make your Button class generic. Depending on how much logic lives in each of these derived classes, this may not work for you.
class Button<T>
{
public T Item { get; private set; }
public Button(string name, T item, ...)
{
// Constructor code
}
}
// Helper class for creation
static class Button
{
public static Button<T> Create<T>(string name, T item, ...)
{
return new Button<T>(name, item, ...);
}
}
Then, to use this:
Button<Company> button = Button.Create("Name", company, ...);

c# downcasting when binding to and interface

Is there a better way of binding a list of base class to a UI other than downcasting e.g:
static void Main(string[] args) {
List<Animal> list = new List<Animal>();
Pig p = new Pig(5);
Dog d = new Dog("/images/dog1.jpg");
list.Add(p);
list.Add(d);
foreach (Animal a in list)
{
DoPigStuff(a as Pig);
DoDogStuff(a as Dog);
}
}
static void DoPigStuff(Pig p)
{
if (p != null)
{
label1.Text = String.Format("The pigs tail is {0}", p.TailLength);
}
}
static void DoDogStuff(Dog d) {
if (d != null)
{
Image1.src = d.Image;
}
}
class Animal {
public String Name { get; set; }
}
class Pig : Animal{
public int TailLength { get; set; }
public Pig(int tailLength)
{
Name = "Mr Pig";
TailLength = tailLength;
}
}
class Dog : Animal {
public String Image { get; set; }
public Dog(String image)
{
Name = "Mr Dog";
Image = image;
}
}
Why not make Animal include an abstract method that Pig and Dog are forced to implement
public class Animal
{
public abstract void DoStuff();
}
public Dog : Animal
{
public override void DoStuff()
{
// Do dog specific stuff here
}
}
public Pig : Animal
{
public override void DoStuff()
{
// Do pig specific stuff here
}
}
This way each specific class takes responsibility for its actions, making your code simpler. You also won't need to cast inside your foreach loop.
When faced with this type of problem, I follow the visitor pattern.
interface IVisitor
{
void DoPigStuff(Piggy p);
void DoDogStuff(Doggy d);
}
class GuiVisitor : IVisitor
{
void DoPigStuff(Piggy p)
{
label1.Text = String.Format("The pigs tail is {0}", p.TailLength);
}
void DoDogStuff(Doggy d)
{
Image1.src = d.Image;
}
}
abstract class Animal
{
public String Name { get; set; }
public abstract void Visit(IVisitor visitor);
}
class Piggy : Animal
{
public int TailLength { get; set; }
public Piggy(int tailLength)
{
Name = "Mr Pig";
TailLength = tailLength;
}
public void Visit(IVisitor visitor)
{
visitor.DoPigStuff(this);
}
}
class Doggy : Animal
{
public String Image { get; set; }
public Doggy(String image)
{
Name = "Mr Dog";
Image = image;
}
public void Visit(IVisitor visitor)
{
visitor.DoDogStuff(this);
}
}
public class AnimalProgram
{
static void Main(string[] args) {
List<Animal> list = new List<Animal>();
Pig p = new Pig(5);
Dog d = new Dog("/images/dog1.jpg");
list.Add(p);
list.Add(d);
IVisitor visitor = new GuiVisitor();
foreach (Animal a in list)
{
a.Visit(visitor);
}
}
}
Thus the visitor pattern simulates double dispatch in a conventional single-dispatch object-oriented language such as Java, Smalltalk, C#, and C++.
The only advantage of this code over jop's is that the IVisitor interface can be implemented on a different class later when you need to add a new type of visitor (like a XmlSerializeVisitor or a FeedAnimalVisitor).
Another way to do this is to perform a typecheck before calling the method:
if (animal is Pig) DoPigStuff();
if (animal is Dog) DoDogStuff();
What you are looking for is multiple-dispatch. NO - C# doesn't support multiple-dispatch. It only supports single-dispatch. C# can only dynamically invoke a method based on the type of the receiver (i.e. the object at the left hand side of the . in the method call)
This code uses double-dispatch. I'll let the code speak for itself:
class DoubleDispatchSample
{
static void Main(string[]args)
{
List<Animal> list = new List<Animal>();
Pig p = new Pig(5);
Dog d = new Dog(#"/images/dog1.jpg");
list.Add(p);
list.Add(d);
Binder binder = new Binder(); // the class that knows how databinding works
foreach (Animal a in list)
{
a.BindoTo(binder); // initiate the binding
}
}
}
class Binder
{
public void DoPigStuff(Pig p)
{
label1.Text = String.Format("The pigs tail is {0}", p.TailLength);
}
public void DoDogStuff(Dog d)
{
Image1.src = d.Image;
}
}
internal abstract class Animal
{
public String Name
{
get;
set;
}
protected abstract void BindTo(Binder binder);
}
internal class Pig : Animal
{
public int TailLength
{
get;
set;
}
public Pig(int tailLength)
{
Name = "Mr Pig";
TailLength = tailLength;
}
protected override void BindTo(Binder binder)
{
// Pig knows that it's a pig - so call the appropriate method.
binder.DoPigStuff(this);
}
}
internal class Dog : Animal
{
public String Image
{
get;
set;
}
public Dog(String image)
{
Name = "Mr Dog";
Image = image;
}
protected override void BindTo(Binder binder)
{
// Pig knows that it's a pig - so call the appropriate method.
binder.DoDogStuff(this);
}
}
NOTE: Your sample code is much more simpler than this. I think of double-dispatch as one of the heavy artilleries in C# programming - I only take it out as a last resort. But if there are a lot of types of objects and a lot different types of bindings that you need to do (e.g. you need to bind it to an HTML page but you also need to bind it to a WinForms or a report or a CSV), I would eventually refactor my code to use double-dispatch.
You're not taking full advantage of your base class. If you had a virtual function in your Animal class that Dog & Pig override, you wouldn't need to cast anything.
Unless you have a more specific example, just override ToString().
I think you want a view-class associated with a factory.
Dictionary<Func<Animal, bool>, Func<Animal, AnimalView>> factories;
factories.Add(item => item is Dog, item => new DogView(item as Dog));
factories.Add(item => item is Pig, item => new PigView(item as Pig));
Then your DogView and PigView will inherit AnimalView that looks something like:
class AnimalView {
abstract void DoStuff();
}
You will end up doing something like:
foreach (animal in list)
foreach (entry in factories)
if (entry.Key(animal)) entry.Value(animal).DoStuff();
I guess you could also say that this is a implementation of the strategy pattern.

Categories

Resources