I am trying to understand the logic behind some C# casting conditions for classes, This is my testing code
File: example.cs
public class Animal { public string animal_name = "Animal"; }
public class Dog : Animal { public string dog_name = "Dog"; }
public class Class1
{
public void createObjects()
{
var animal1 = new Animal();
printAnimalName(animal1);
}
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name);
}
}
In my Main function, I call the call createObjects function as follows:
static void Main(string[] args)
{
Class1 c1 = new Class1();
c1.createObjects();
Console.ReadLine();
}
Running the code above gives an error
System.NullReferenceException:'Object reference not set to an instance of an object'
I understand that this is the way it should be, due to the casting in:
var dog1 = my_animal as Dog;
But what is the logic behind it? Why can't we call the function printAnimalName by passing an Animal object for it? This should be possible as per my understanding, because the function expects an Animal object.
After that var dog1 = my_animal as Dog; // dog1 is of type Dog you need to add only null check:
if(dog1 != null)
{
Console.WriteLine(dog1.dog_name);
}
I think you need to learn about polymorphism, abscract classes and interfaces.
public abstract class FourLeggedAnimal
{
public int GetLegCount()
{
return 4;
}
}
public class Dog : FourLeggedAnimal
{
public string GetScientificName()
{
return "doggus scientificus";
}
}
public class Cat : FourLeggedAnimal
{
public string GetServant()
{
return "human";
}
}
public class AnimalInformer
{
public void DisplayInformation(FourLeggedAnimal animal)
{
Console.WriteLine("It has {0} legs", animal.GetLegCount());
if (animal is Dog)
Console.WriteLine("Its scientific name is {0}", ((Dog)animal).GetScientificName());
if (animal is Cat)
Console.WriteLine("Its servant is {0}", ((Cat)animal).GetServant());
}
}
Here you use the absract class to provide base functionality to all other classes derived from it. All classes derived from FourLeggedAnimal have a method GetLegCount() that returns the number of legs.
But a cat has a servant a dog doesnt have, it just has a friend(both humans, but different relations). So the dog needs no method "GetServant" but the cat does. -> Differenct implementations in 2 seperate classes
Another example with interfaces is that each derived class needs to provide that functionality.
public interface IMovableObject
{
int GetMaxSpeed();
}
public class Car : IMovableObject
{
public int GetMaxSpeed()
{
return 100;
}
}
public class Human : IMovableObject
{
public int GetMaxSpeed()
{
return 20;
}
}
public static class SpeedChecker
{
public static void CheckSpeed(IMovableObject speedster)
{
Console.WriteLine("Checking Speed..");
int speed = speedster.GetMaxSpeed();
if (speed > 50)
Console.WriteLine("It's really fast!");
else
Console.WriteLine("Just a turtle or something similar...");
}
}
Now, if you have a Method getting a IMovableObject that is actually a car, you call the implementation of Car:
Car c = new Car();
Human h = new Human();
Console.WriteLine("Checking Car..");
SpeedChecker.CheckSpeed(c);
Console.WriteLine("Checking Human..");
SpeedChecker.CheckSpeed(h);
-> returns:
Checking Car...
Checking Speed...
It's really fast!
Checking Human...
Checking Speed...
Just a turtle or something similar...
These are 2 uses where you derive classes and use castings to get certain functionality or use the basetype without casting but still getting different functionality
Your problem is here:
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name); //Animal does not have this property!
}
Casting does not invoke a constructor. This means that dog_name is null, as my_animal does not have a dog_name property. I think you missed something on inheritance here.
This is actually an example that happens in more complex form in the real world; Given class A, B inherits from A. Both have the same properties because of inheritance. Then someone makes a different property with a similar, but not congruous property name and uses it for the same function in the child object. Welcome to code smell city.
To fix your function so it comes across as a dog, you'd do two things:
public class Animal { public string animal_name = "Animal"; }
//since we want a different default, we can
//can make the change in the constructor
public class Dog : Animal
{
Dog(){ this.animal_name = "Dog"; }
//if you really, really want a second name string, you can do this:
public string Dog_Name
{
get { return this.animal_name; }
set { this.animal_name = value; }
}
}
Then, you need to make your method call the appropriate property.
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.animal_name);
}
I also recommend changing your public fields to properties and possibly override ToString() when all you want to do with an object is return a string representing it.
Related
I have the following classes
public abstract class BaseViewPresenter { }
public abstract class BaseView<T> : UserControl
where T : BaseViewPresenter { }
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter> { }
I have a method that looks like this (simplified)
public BaseView<BaseViewPresenter> Resolve(BaseViewPresenter model)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
// Correctly creates BaseView object
var control = Activator.CreateInstance(viewType);
// Fails to cast as BaseView<BaseViewPresenter> so returns null
return control as BaseView<BaseViewPresenter>;
}
When I call this using an instances of LoginPresenter
var login = new LoginPresenter();
var ctl = Resolve(login);
The line Activator.CreateInstance(viewType) correctly resolves into a new instances of my LoginView, however control as BaseView<BaseViewPresenter> can't do the cast correctly so returns null.
Is there a way to correctly cast the control into BaseView<BaseViewPresenter> without using specific type generics?
Since LoginView inherits from BaseView<LoginPresenter>, and LoginPresenter inherits from BaseViewPresenter, I would assume there's a way to convert LoginView to BaseView<BaseViewPresenter>.
I am stuck with using .Net 3.5
This is a very frequently asked question. Let's rename your types:
abstract class Fruit { } // was BaseViewPresenter
abstract class FruitBowl<T> where T : Fruit // was BaseView
class Apple : Fruit { } // was LoginPresenter
class BowlOfApples : FruitBowl<Apple> { } // was LoginView
Your question now is:
I have a BowlOfApples, which inherits from FruitBowl<Apple>. Why can I not use it as a FruitBowl<Fruit>? An apple is a fruit, so a bowl of apples is a bowl of fruit.
No, it isn't. You can put a banana in a bowl of fruit, but you can't put a banana in a bowl of apples, and therefore a bowl of apples is not a bowl of fruit. (And by similar argument, a bowl of fruit is not a bowl of apples either.) Since the operations you can legally perform on the two types are different, they cannot be compatible.
Here is a photo of StackOverflow legend Jon Skeet demonstrating this fact:
The feature you want is called generic contravariance, and it is supported only on interfaces and delegate types when the compiler can prove that the variance is safe, and when the varying type is a reference type. For example, you can use an IEnumerable<Apple> in a context where IEnumerable<Fruit> is needed because the compiler can verify that there is no way that you can put a Banana into a sequence of fruit.
Do a search on "C# covariance and contravariance" on this site or on the web and you'll find many more details about how this feature works. In particular, my series of articles on how we designed and implemented this feature in C# 4 starts here: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx
I accepted Eric's answer since it provides a great explanation of why what I wanted wasn't possible, but I also thought I'd share my solution in case anyone else runs into this same problem.
I removed the generic type parameter from my original BaseView class, and created a 2nd version of the BaseView class that included the generic type parameter and specifics for it.
The first version is used by my .Resolve() method or other code that doesn't care about the specific types, and the second version is used by any code that does care, such as the implentation of a BaseView
Here's an example of how my code ended up looking
// base classes
public abstract class BaseViewPresenter { }
public abstract class BaseView : UserControl
{
public BaseViewPresenter Presenter { get; set; }
}
public abstract class BaseView<T> : BaseView
where T : BaseViewPresenter
{
public new T Presenter
{
get { return base.Presenter as T; }
set { base.Presenter = value; }
}
}
// specific classes
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter>
{
// Can now call things like Presenter.LoginPresenterMethod()
}
// updated .Resolve method used for obtaining UI object
public BaseView Resolve(BaseViewPresenter presenter)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
BaseView view = Activator.CreateInstance(viewType) as BaseView;
view.Presenter = presenter;
return view;
}
You're expecting to treat the type as being covariant with respect to the generic argument. Classes can never be covariant; you'd need to use an interface rather than (or in addition to) an abstract class to make it covariant with respect to T. You'd also need to be using C# 4.0.
My usual solution to this problem is to create an intermediary class that has access to the type-parametric class's methods through delegates. Fields can also be accessed through getters/setters.
The general pattern goes:
public abstract class Super {}
public abstract class MyAbstractType<T> where T : Super {
public MyGeneralType AsGeneralType() {
return MyGeneralType.Create(this);
}
// Depending on the context, an implicit cast operator might make things
// look nicer, though it might be too subtle to some tastes.
public static implicit operator MyGeneralType(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
public int field;
public void MyMethod1() {}
public void MyMethod2(int argument) {}
public abstract bool MyMethod3(string argument);
}
public delegate T Getter<T>();
public delegate void Setter<T>(T value);
public delegate void MyMethod1Del();
public delegate void MyMethod2Del(int argument);
public delegate bool MyMethod3Del(string argument);
public class MyGeneralType {
public Getter<int> FieldGetter;
public Setter<int> FieldSetter;
public MyMethod1Del MyMethod1;
public MyMethod2Del MyMethod2;
public MyMethod3Del MyMethod3;
public static MyGeneralType Create<T>(MyAbstractType<T> t) where T : Super {
var g = new MyGeneralType();
g.FieldGetter = delegate { return t.field; };
g.FieldSetter = value => { t.field = value; };
g.MyMethod1 = t.MyMethod1;
g.MyMethod2 = t.MyMethod2;
g.MyMethod3 = t.MyMethod3;
return g;
}
public int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
The above exemplifies getting all the methods and fields but normally I only need a few of them. This is a general solution to the problem and one could feasibly write a tool to generate these intermediary classes automatically, which I might at some point.
Try it here: https://dotnetfiddle.net/tLkmgR
Note that this is enough for all my cases, but you can be extra hacky with this:
public abstract class MyAbstractType<T> where T : Super {
// ... Same everything else ...
// data fields must become abstract getters/setters, unfortunate
public abstract int field {
get;
set;
}
public static implicit operator MyAbstractType<Super>(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
}
public class MyGeneralType : MyAbstractType<Super> {
// ... same constructors and setter/getter
// fields but only keep method fields
// that contain the method references for
// implementations of abstract classes,
// and rename them not to clash with the
// actual method names ...
public MyMethod3Del myMethod3Ref;
// Implement abstract methods by calling the corresponding
// method references.
public override bool MyMethod3(string argument) {
return myMethod3Ref(argument);
}
// Same getters/setters but with override keyword
public override int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
And there you go, now you can literally cast a MyAbstractType<Sub> where Sub : Super to a MyAbstractType<Super>, although it's no longer the same object anymore, but it does retain the same methods and data, it's sort of a complex pointer.
public class Sub : Super {}
public class MySubType : MyAbstractType<Sub> {
public int _field;
public override int field {
get { return _field; }
set { _field = value; }
}
public override bool MyMethod3(string argument) {
Console.WriteLine("hello " + argument);
return argument == "world";
}
}
public class MainClass {
public static void Main() {
MyAbstractType<Sub> sub = new MyAbstractType<Sub>();
MyAbstractType<Super> super = sub;
super.MyMethod3("hello"); // calls sub.MyMethod3();
super.field = 10; // sets sub.field
}
}
This isn't as good in my opinion, the other version of MyGeneralType is a more straighforward layer over the concrete types, plus it doesn't require rewriting the data fields, but it does actually answer the question, technically. Try it here: https://dotnetfiddle.net/S3r3ke
Example
Using these abstract classes:
public abstract class Animal {
public string name;
public Animal(string name) {
this.name = name;
}
public abstract string Sound();
}
public abstract class AnimalHouse<T> where T : Animal {
List<T> animals;
public AnimalHouse(T[] animals) {
this.animals = animals.ToList();
}
public static implicit operator GeneralAnimalHouse(AnimalHouse<T> house) {
return GeneralAnimalHouse.Create(house);
}
public List<string> HouseSounds() {
return animals.Select(animal => animal.Sound()).ToList();
}
}
We make this "general" variant:
public delegate List<string> HouseSoundsDel();
public class GeneralAnimalHouse {
public HouseSoundsDel HouseSounds;
public static GeneralAnimalHouse Create<T>(AnimalHouse<T> house) where T : Animal {
var general = new GeneralAnimalHouse();
general.HouseSounds = house.HouseSounds;
return general;
}
}
And finally with these inheritors:
public class Dog : Animal {
public Dog(string name) : base(name) {}
public override string Sound() {
return name + ": woof";
}
}
public class Cat : Animal {
public Cat(string name) : base(name) {}
public override string Sound() {
return name + ": meow";
}
}
public class DogHouse : AnimalHouse<Dog> {
public DogHouse(params Dog[] dogs) : base(dogs) {}
}
public class CatHouse : AnimalHouse<Cat> {
public CatHouse(params Cat[] cats) : base(cats) {}
}
We use it like this:
public class AnimalCity {
List<GeneralAnimalHouse> houses;
public AnimalCity(params GeneralAnimalHouse[] houses) {
this.houses = houses.ToList();
}
public List<string> CitySounds() {
var random = new Random();
return houses.SelectMany(house => house.HouseSounds())
.OrderBy(x => random.Next())
.ToList();
}
}
public class MainClass {
public static void Main() {
var fluffy = new Cat("Fluffy");
var miu = new Cat("Miu");
var snuffles = new Cat("Snuffles");
var snoopy = new Dog("Snoopy");
var marley = new Dog("Marley");
var megan = new Dog("Megan");
var catHouse = new CatHouse(fluffy, miu, snuffles);
var dogHouse = new DogHouse(snoopy, marley, megan);
var animalCity = new AnimalCity(catHouse, dogHouse);
foreach (var sound in animalCity.CitySounds()) {
Console.WriteLine(sound);
}
}
}
Output:
Miu: meow
Snoopy: woof
Snuffles: meow
Fluffy: meow
Marley: woof
Megan: woof
Notes:
I added names so it's clear that the method references carry their owner's data with them, for those unfamiliar with delegates.
The required using statements for this code are System, System.Collections.Generic, and System.Linq.
You can try it here: https://dotnetfiddle.net/6qkHL3#
A version that makes GeneralAnimalHouse a subclass of AnimalHouse<Animal> can be found here: https://dotnetfiddle.net/XS0ljg
I have the below problem. Look my structure of code.
This will be ok if all my derived classes have the same sequence of methods in Process(Animal a). But imagine I have Turtle class, that extends Animal and when Process(Animal a) is called the methods inside have to be in different order and class Turtle has some extra methods for example Sleep.
What should I do in that case?
Thanks
public class Animal
{
public virtual string Eat(){ return "I'm eating"; }
public virtual string MakeNoise() { return "I'm ";}
public virtual string Go() { return "I'm walking"; }
}
public class Dog : Animal
{
public override string Eat()
{
return string.Format("{0} {1}",base.Eat(),"a pie");
}
public override string MakeNoise()
{
return string.Format("{0} {1}",base.MakeNoise(),"barking");
}
}
public class Controller
{
public void Process(Animal a)
{
a.Eat();
a.MakeNoise();
a.Go;
}
}
public class Client
{
IList<Animal> animals= new List<Animal>(){Dog,Cat,Turtle,Mouse}; //all animals have base class Animal
Controller = new Controller();
foreach(Animal a in animals)
{
p.Process(a);
}
}
You can add an overloaded method
public void Process(Turtle t)
{
//Do what you want here
}
You could write yourself a Controller factory that will return an appropriate controller for a given animal. Create a sub-class of Controller for Turtle, etc. Here I've assumed that we can extract an interface IControler, and IAnimal, but you could use abstract base types instead.
public class ControllerFactory
{
public static IController GetController (IAnimal animalToControl)
{
if (animalToControl is Turtle) { return new TurtleController(); }
if (animalToControl is Sheep) { return new SheepController(); }
// default
return new Controller();
}
}
and call with:
foreach(Animal a in animals)
{
var p = ControllerFactory.GetController(a);
p.Process(a);
}
The implementation of the factory here is crude, but illustrates the point.
Each animal has Eat, MakeNoise, and Go, but the sequence varies by animal (plus some additional behaviors for some animals.) Will the sequence always be the same for the given animal? Is the only reason why they inherit from Animal so that they can share the same base behaviors and only override when they need to?
If so then perhaps instead of a Process method in a controller there should be an ExecuteBehaviors method on the Animal which can be overridden by individual animals.
public virtual void ExecuteBehaviors()
{
Eat();
MakeNoise();
Go();
}
And then if an animal needs a different sequence it can override that method.
That seems to meet the description of your problem, to allow each animal to inherit behaviors but control their sequence and add new behaviors.
Then in your controller you can just call ExecuteBehavior for each animal. That's real polymorphism at work. You can treat any instance of Animal the same and call the same method on it whether it's a Dog or a Turtle, even though their behaviors will vary.
You have two options, the first one is extend the Process method. You can make a switch inside and define the order when a.GetType() == typeof(Turtle).
public class Controller
{
public void Process(Animal a)
{
if(a.GetType() == typeof(Turtle)
{
((Turtle)a).YourMethod();
}
else
{
a.Eat();
a.MakeNoise();
a.Go;
}
}
}
Or you can make the Animal class responsible for the Process method.
The idea here I think is not make Animal class responsible of Process method. That is where Controller come in action. Try to use a decorator pattern or a Factory for each Animal, as #Brett said
So I'm used to working with javascript, and being able to simply do
dog={};
dog.name="Rex";
dog.examine=function(){console.log("This is a dog. Its name is "+this.name+".");}
cat={};
cat.name="Phil Collins";
cat.examine=function(){console.log("This is a cat. Its name is "+this.name+".");}
dog.examine();
cat.examine();
This would return, of course : This is a dog. Its name is Rex. and This is a cat. Its name is Phil Collins.
I've started learning xna, and I'm very confused by this whole lambda/delegate/action system. I'm not sure what syntax to use, the compiler gets angry when I try to make a function with no input or output variables, and I'm having trouble keeping the proper scope for this. Could someone please help me find out how I'd port the above code into c#?
I made this a Community Wiki because this question is really too broad, C# and JavaScript are very different things and answer can't be complete. I'll just sketch a direction but the way to go is to learn C# and differences will be clear. That's the reason I'll try to first write something similar to JavaScript program you posted and then, step by step, to change it to be more C# style.
Let me also say that if you extensively want to use dynamic typing in C# (or JavaScript programming style) then (probably)...you picked wrong language.
Step 1
Something somehow close to what you write can be written in C# like this (let me use this example to highlight differences, you really have to buy a good C# book and start from there):
dynamic dog = new ExpandoObject();
dog.Name = "Pluto";
dog.Hello = new Action(() => Console.WriteLine("This is a dog named {0}", dog.Name));
dog.Hello();
First of all you see that in C# a variable must be typed, in this case with dynamic we bypass static typing and we may even change content later (but this is another story). ExpandoObject is a special object that can be expanded adding properties, it's not normal C# behavior where almost everything about types is checked at compile-times (don't think about casts, now).
Second line is pretty similar, nothing new (for you) here but pretty strange if you're a traditional C# programmer.
Finally the interesting part: we add a property that is a delegate (using a lambda) but here there is a big difference (you also noted by yourself): this has a different meaning in C# and within a method this is the instance of the object where method is declared (OK it's declared in the class but you know what I mean). Let's watch this: dog.Name, we captured dog variable inside our anonymous method (as you would do in JavaScript).
Step 2
It's just a starting point because design and philosophy is completely different, same thing in C# should be done with an Animal base class and Dog + Cat derived classes but you'll learn this by yourself. Let me do just one more simple step in that direction:
var typedDog = new {
Name = "Pluto",
Hello = new Action(() => Console.WriteLine("This is a dog named {0}", Name))
};
typedDog.Hello();
Maybe you don't see such big difference but this code is strongly typed! What does it means? We declared an anonymous class with two properties and one of them is a delegate, we still can't use this and in C# (unlike Java) we can't declare methods in anonymous types but now compiler knows (then it's compile-time) what things are. For example:
dog.Name = 2; // Valid, now Name is an integer
dog.Hello = 2; // Valid, also Hello is an integer
dog.Hello(); // This will fail at run-time because Hello now isn't a delegate
Is it bad, right? With our new typed object this isn't possible:
typedDog.Name = 2; // Compile-time error, Name is a string
typedDog.Hello = 2; // Compile-time error, Hello must be an Action delegate
Of course we can assign a new anonymous delegate to replace old one (but type must match):
typedDog.Hello = new Action(() => Console.WriteLine("This is a typed dog named {0}", typedDog.Name));
Step 3
This has been extensively described in other answers so I won't repeat, just to sketch things:
class Animal {
public string Name { get; set; }
public abstract void Hello();
}
class Dog : Animal {
public override void Hello() {
Console.WriteLine("This is a dog named {0}", this.Name);
}
}
Note that now you finally have this pointer and it does what you expect. It's used like this:
var dog = new Dog { Name = "Pluto" };
dog.Hello();
Note that in JavaScript you can even write this:
var anInteger = 2;
anInteger.PrintSomething();
That's not allowed in C# because at compile-time (unless you use dynamic variables) it needs to know if PrintSomething() is a method and how to call it. Same thing can be also done like this (using interfaces):
class IPolite {
void Hello();
}
class Dog : IPolite {
public string Name { get; set; }
public void Hello() {
Console.WriteLine("This is a dog named {0}", this.Name);
}
}
Now you can even have a completely different object:
class Car : IPolite {
public string Name { get; set; }
public void Hello() {
Console.WriteLine("This is a car, name is {0}", this.Name);
}
}
It can be used like this:
IPolite thing = new Dog { Name = "Pluto" };
thing.Hello();
thing = new Car { Name = "Ferrari F50" };
thing.Hello();
Please note we're reusing same thing variable. Many other things to see and to do...
In general C# and other strongly-typed languages are VASTLY different from script / run-time languages like JS. C# is a compiled language and this "strongly-typed" nature is ensured by the compiler. This is true for many type-safe (http://en.wikipedia.org/wiki/Type_safety) languages.
Generally speaking a class structure in C# would look like this:
public abstract class Animal {
//Fields or instance variables are typically hidden from the outside world (consuming code). This is controlled by the 'access-modifier' in this case, private.
private string _name;
//Constructor is called when you use the 'new' keyword to instantiate an instance of a type that derives from Animal (Animal cannot be instantiated directly because it is abstract).
protected Animal() {
//Avoids null references unless someone overrides the property setter, for this example, it's safe enough
_name = string.Empty;
}
//This is syntax for declaring a property
//properties are publicly accessible pieces of data that control access to a basic
// field (variable).
// It allows you to apply logic to the field it wraps.
// In this example, the field cannot be set to a null or empty string (except by the constructor, which bypasses the property.
public virtual string Name {
get {
return _name;
} set {
if(!String.IsNullOrWhiteSpace(value)) {
_name = value;
}
}
} // end property Name
//This is a method that must be overridden by any derived type that is not abstract and may (or may not) be overridden by a derived type that is abstract.
public abstract void Examine();
}
public class Cat : Animal {
public Cat : base() {}
public override void Examine() {
Console.WriteLine(String.Concat("This is a cat. It's name is ", this.Name, "."));
}
}
public Class Dog : Animal {
public Dog() : base() {}
public override void Examine() {
Console.WriteLine(String.Concat("This is a dog. It's name is ", this.Name, "."));
}
}
//In some runnable code elsewhere like a console application:
Animal cat = new Cat() {Name = "Mittens"};
Animal dog = new Dog() {Name = "Fido"};
cat.Examine();
dog.Examine();
For more information about access modifies, see here:http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx
You could use inheritance to accomplish it:
public class Animal
{
public string Name { get; private set; }
public Animal(string name)
{
this.Name = name;
}
public void Examine()
{
Console.WriteLine("This is a {0}. Its name is {1}.", this.GetType(), Name);
}
}
public void Dog : Animal
{
public Dog(string name) : base(name) { }
}
public void Cat : Animal
{
public Cat(string name) : base(name) { }
}
Then you can create instances of these derived types:
static class Main(string[] args)
{
Dog rex = new Dog("rex");
Cat phil = new Cat("Phil Collins");
rex.Examine();
phil.Examine();
}
Here's a simple example. I'd strongly suggest picking up a book or checking out a tutorial because this stuff will be covered pretty early on.
public abstract class Animal
{
public string Type { get; private set; }
public string Name { get; set; }
protected Animal(string type)
{
Type = type;
}
public virtual string Examine()
{
return string.Format("This is a {0}. Its name is {1}.", Type, Name);
}
}
public class Dog : Animal
{
public Dog() : base("Dog")
{
}
}
public class Cat : Animal
{
public Cat() : base("Cat")
{
}
}
var dog = new Dog { Name = "Rex" };
var cat = new Cat { Name = "Phil Collins" };
You can use the so-called anonymous functions or you could make this examine function of yours to be a property of type Action. For e.g., you could write:
Animal.cs:
public abstract class Animal
{
public string Name { get; set; }
public Action Examine { get; set;}
}
Dog.cs:
public class Dog : Animal
{
}
Cat.cs:
public class Cat : Animal
{
}
And then, somewhere where you could use this, you can say:
Dog dog = new Dog { Name = "Rex" };
dog.Examine = delegate
{
Console.WriteLine("This is a dog. Its name is {0}.", dog.Name);
};
Cat cat = new Cat { Name = "Phil Collins" };
cat.Examine = delegate
{
Console.WriteLine("This is a cat. Its name is {0}.", cat.Name);
};
dog.Examine();
cat.Examine();
Bear in mind that instead of using 'this', you're using a reference to the previously instantiated class which extends Animal (Dog or Cat).
There's also the other option... Combining ExpandoObject class and a dynamic keyword:
dynamic dog = new ExpandoObject();
dog.Name = "Rex";
Action examineDog = delegate {
Console.WriteLine("This is a dog. Its name is {0}.", dog.Name);
};
dog.Examine = examineDog;
dynamic cat = new ExpandoObject();
cat.Name = "Phil Collins";
Action examineCat = delegate
{
Console.WriteLine("This is a cat. Its name is {0}.", cat.Name);
};
cat.Examine = examineCat;
dog.Examine();
cat.Examine();
I have the following classes
public abstract class BaseViewPresenter { }
public abstract class BaseView<T> : UserControl
where T : BaseViewPresenter { }
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter> { }
I have a method that looks like this (simplified)
public BaseView<BaseViewPresenter> Resolve(BaseViewPresenter model)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
// Correctly creates BaseView object
var control = Activator.CreateInstance(viewType);
// Fails to cast as BaseView<BaseViewPresenter> so returns null
return control as BaseView<BaseViewPresenter>;
}
When I call this using an instances of LoginPresenter
var login = new LoginPresenter();
var ctl = Resolve(login);
The line Activator.CreateInstance(viewType) correctly resolves into a new instances of my LoginView, however control as BaseView<BaseViewPresenter> can't do the cast correctly so returns null.
Is there a way to correctly cast the control into BaseView<BaseViewPresenter> without using specific type generics?
Since LoginView inherits from BaseView<LoginPresenter>, and LoginPresenter inherits from BaseViewPresenter, I would assume there's a way to convert LoginView to BaseView<BaseViewPresenter>.
I am stuck with using .Net 3.5
This is a very frequently asked question. Let's rename your types:
abstract class Fruit { } // was BaseViewPresenter
abstract class FruitBowl<T> where T : Fruit // was BaseView
class Apple : Fruit { } // was LoginPresenter
class BowlOfApples : FruitBowl<Apple> { } // was LoginView
Your question now is:
I have a BowlOfApples, which inherits from FruitBowl<Apple>. Why can I not use it as a FruitBowl<Fruit>? An apple is a fruit, so a bowl of apples is a bowl of fruit.
No, it isn't. You can put a banana in a bowl of fruit, but you can't put a banana in a bowl of apples, and therefore a bowl of apples is not a bowl of fruit. (And by similar argument, a bowl of fruit is not a bowl of apples either.) Since the operations you can legally perform on the two types are different, they cannot be compatible.
Here is a photo of StackOverflow legend Jon Skeet demonstrating this fact:
The feature you want is called generic contravariance, and it is supported only on interfaces and delegate types when the compiler can prove that the variance is safe, and when the varying type is a reference type. For example, you can use an IEnumerable<Apple> in a context where IEnumerable<Fruit> is needed because the compiler can verify that there is no way that you can put a Banana into a sequence of fruit.
Do a search on "C# covariance and contravariance" on this site or on the web and you'll find many more details about how this feature works. In particular, my series of articles on how we designed and implemented this feature in C# 4 starts here: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx
I accepted Eric's answer since it provides a great explanation of why what I wanted wasn't possible, but I also thought I'd share my solution in case anyone else runs into this same problem.
I removed the generic type parameter from my original BaseView class, and created a 2nd version of the BaseView class that included the generic type parameter and specifics for it.
The first version is used by my .Resolve() method or other code that doesn't care about the specific types, and the second version is used by any code that does care, such as the implentation of a BaseView
Here's an example of how my code ended up looking
// base classes
public abstract class BaseViewPresenter { }
public abstract class BaseView : UserControl
{
public BaseViewPresenter Presenter { get; set; }
}
public abstract class BaseView<T> : BaseView
where T : BaseViewPresenter
{
public new T Presenter
{
get { return base.Presenter as T; }
set { base.Presenter = value; }
}
}
// specific classes
public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter>
{
// Can now call things like Presenter.LoginPresenterMethod()
}
// updated .Resolve method used for obtaining UI object
public BaseView Resolve(BaseViewPresenter presenter)
{
var type = model.GetType();
var viewType = _dataTemplates[type];
BaseView view = Activator.CreateInstance(viewType) as BaseView;
view.Presenter = presenter;
return view;
}
You're expecting to treat the type as being covariant with respect to the generic argument. Classes can never be covariant; you'd need to use an interface rather than (or in addition to) an abstract class to make it covariant with respect to T. You'd also need to be using C# 4.0.
My usual solution to this problem is to create an intermediary class that has access to the type-parametric class's methods through delegates. Fields can also be accessed through getters/setters.
The general pattern goes:
public abstract class Super {}
public abstract class MyAbstractType<T> where T : Super {
public MyGeneralType AsGeneralType() {
return MyGeneralType.Create(this);
}
// Depending on the context, an implicit cast operator might make things
// look nicer, though it might be too subtle to some tastes.
public static implicit operator MyGeneralType(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
public int field;
public void MyMethod1() {}
public void MyMethod2(int argument) {}
public abstract bool MyMethod3(string argument);
}
public delegate T Getter<T>();
public delegate void Setter<T>(T value);
public delegate void MyMethod1Del();
public delegate void MyMethod2Del(int argument);
public delegate bool MyMethod3Del(string argument);
public class MyGeneralType {
public Getter<int> FieldGetter;
public Setter<int> FieldSetter;
public MyMethod1Del MyMethod1;
public MyMethod2Del MyMethod2;
public MyMethod3Del MyMethod3;
public static MyGeneralType Create<T>(MyAbstractType<T> t) where T : Super {
var g = new MyGeneralType();
g.FieldGetter = delegate { return t.field; };
g.FieldSetter = value => { t.field = value; };
g.MyMethod1 = t.MyMethod1;
g.MyMethod2 = t.MyMethod2;
g.MyMethod3 = t.MyMethod3;
return g;
}
public int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
The above exemplifies getting all the methods and fields but normally I only need a few of them. This is a general solution to the problem and one could feasibly write a tool to generate these intermediary classes automatically, which I might at some point.
Try it here: https://dotnetfiddle.net/tLkmgR
Note that this is enough for all my cases, but you can be extra hacky with this:
public abstract class MyAbstractType<T> where T : Super {
// ... Same everything else ...
// data fields must become abstract getters/setters, unfortunate
public abstract int field {
get;
set;
}
public static implicit operator MyAbstractType<Super>(MyAbstractType<T> t) {
return MyGeneralType.Create(t);
}
}
public class MyGeneralType : MyAbstractType<Super> {
// ... same constructors and setter/getter
// fields but only keep method fields
// that contain the method references for
// implementations of abstract classes,
// and rename them not to clash with the
// actual method names ...
public MyMethod3Del myMethod3Ref;
// Implement abstract methods by calling the corresponding
// method references.
public override bool MyMethod3(string argument) {
return myMethod3Ref(argument);
}
// Same getters/setters but with override keyword
public override int field {
get { return FieldGetter(); }
set { FieldSetter(value); }
}
}
And there you go, now you can literally cast a MyAbstractType<Sub> where Sub : Super to a MyAbstractType<Super>, although it's no longer the same object anymore, but it does retain the same methods and data, it's sort of a complex pointer.
public class Sub : Super {}
public class MySubType : MyAbstractType<Sub> {
public int _field;
public override int field {
get { return _field; }
set { _field = value; }
}
public override bool MyMethod3(string argument) {
Console.WriteLine("hello " + argument);
return argument == "world";
}
}
public class MainClass {
public static void Main() {
MyAbstractType<Sub> sub = new MyAbstractType<Sub>();
MyAbstractType<Super> super = sub;
super.MyMethod3("hello"); // calls sub.MyMethod3();
super.field = 10; // sets sub.field
}
}
This isn't as good in my opinion, the other version of MyGeneralType is a more straighforward layer over the concrete types, plus it doesn't require rewriting the data fields, but it does actually answer the question, technically. Try it here: https://dotnetfiddle.net/S3r3ke
Example
Using these abstract classes:
public abstract class Animal {
public string name;
public Animal(string name) {
this.name = name;
}
public abstract string Sound();
}
public abstract class AnimalHouse<T> where T : Animal {
List<T> animals;
public AnimalHouse(T[] animals) {
this.animals = animals.ToList();
}
public static implicit operator GeneralAnimalHouse(AnimalHouse<T> house) {
return GeneralAnimalHouse.Create(house);
}
public List<string> HouseSounds() {
return animals.Select(animal => animal.Sound()).ToList();
}
}
We make this "general" variant:
public delegate List<string> HouseSoundsDel();
public class GeneralAnimalHouse {
public HouseSoundsDel HouseSounds;
public static GeneralAnimalHouse Create<T>(AnimalHouse<T> house) where T : Animal {
var general = new GeneralAnimalHouse();
general.HouseSounds = house.HouseSounds;
return general;
}
}
And finally with these inheritors:
public class Dog : Animal {
public Dog(string name) : base(name) {}
public override string Sound() {
return name + ": woof";
}
}
public class Cat : Animal {
public Cat(string name) : base(name) {}
public override string Sound() {
return name + ": meow";
}
}
public class DogHouse : AnimalHouse<Dog> {
public DogHouse(params Dog[] dogs) : base(dogs) {}
}
public class CatHouse : AnimalHouse<Cat> {
public CatHouse(params Cat[] cats) : base(cats) {}
}
We use it like this:
public class AnimalCity {
List<GeneralAnimalHouse> houses;
public AnimalCity(params GeneralAnimalHouse[] houses) {
this.houses = houses.ToList();
}
public List<string> CitySounds() {
var random = new Random();
return houses.SelectMany(house => house.HouseSounds())
.OrderBy(x => random.Next())
.ToList();
}
}
public class MainClass {
public static void Main() {
var fluffy = new Cat("Fluffy");
var miu = new Cat("Miu");
var snuffles = new Cat("Snuffles");
var snoopy = new Dog("Snoopy");
var marley = new Dog("Marley");
var megan = new Dog("Megan");
var catHouse = new CatHouse(fluffy, miu, snuffles);
var dogHouse = new DogHouse(snoopy, marley, megan);
var animalCity = new AnimalCity(catHouse, dogHouse);
foreach (var sound in animalCity.CitySounds()) {
Console.WriteLine(sound);
}
}
}
Output:
Miu: meow
Snoopy: woof
Snuffles: meow
Fluffy: meow
Marley: woof
Megan: woof
Notes:
I added names so it's clear that the method references carry their owner's data with them, for those unfamiliar with delegates.
The required using statements for this code are System, System.Collections.Generic, and System.Linq.
You can try it here: https://dotnetfiddle.net/6qkHL3#
A version that makes GeneralAnimalHouse a subclass of AnimalHouse<Animal> can be found here: https://dotnetfiddle.net/XS0ljg
Suppose I have these codes (and the classes are in the same namespace):
class Animal
{
int numberOfLegs = 4; // initialized
public int returnNumberOfLegs()
{
return numberOfLegs;
}
}
class Snake
{
internal Animal myAnimalObject = new Animal();
myAnimalObject.numberOfLegs = 0; // why is this line not allowed?
}
class Program
{
public static void Main(string [] args)
{
Snake mySnakeObject = new Snake();
Console.WriteLine("Snake");
Console.WriteLine("Number of Legs: {0}", mySnakeObject.myAnimalObject.returnNumberOfLegs());
}
}
Observe the class Snake. When I place these 2 lines of code in Main(), it is possible/allowed and will work if I declare the variable numberOfLegs with the right access modifier. Why can't I do it in the class Snake itself? What should I do to allow it?
Note that the 2nd line of code from class Snake is invalid and these are the errors it produced:
1) Error 1 Invalid token '=' in class, struct, or interface member declaration
2) Error 2 'myNamespaceName.Snake.myAnimalObject' is a 'field' but is used like a 'type'
Thanks. I just want to learn about this.
Edit:
Okay, thanks guys. I know about constructors and inheritance, but somehow, I'm being forced to do it "the hard and not-so-smart" way, for learning purposes(?). And that I even had to set the default value to 4. Thank you for your replies. Plus, I just made up these classes.
Because executable code should be placed either in constructor or in some method/property.
You cannot place code just inside the class, put it in the constructor.
class Snake
{
internal Animal myAnimalObject = new Animal();
public Snake()
{
myAnimalObject.numberOfLegs = 0;
}
}
When you write
internal Animal myAnimalObject = new Animal();
in the class body, it's a kind of a syntax sugar; compiler will create constructor and put your code line inside it.
and it will look like
class Snake
{
internal Animal myAnimalObject;
public Snake()
{
myAnimalObject = new Animal();
myAnimalObject.numberOfLegs = 0;
}
}
First of all, you can't do this in the class initializer:
myAnimalObject.numberOfLegs = 0;
Since you're not setting a class member itself, but rather interacting with a class member, you'd have to do it in the constructor:
public Snake()
{
myAnimalObject.numberOfLegs = 0;
}
Also, in order to access numberOfLegs it would need to be internal or public:
internal int numberOfLegs = 4; // initialized
More to the point of the whole scenario however, this seems like a very odd abstraction. Though part of me applauds the use of composition instead of inheritance, this seems more like a case where inheritance is warranted. It seems that Animal really shouldn't be initializing any value for numberOfLegs by default. Indeed, Animal shouldn't even be a concrete object given the real-world concepts being modeled. Instead, I might try something like:
abstract class Animal
{
public abstract int NumberOfLegs { get; }
}
class Snake : Animal
{
public override int NumberOfLegs { get { return 0; } }
}
The idea being that a Snake is an Animal, that an Animal by itself can't exist unless it's a specific type of Animal, and that each individual type of Animal internally controls its own values and all the abstract Animal class does is define what those values need to be.
You should use inheritance instead. Make Animal an abstract class, base class for all animals. Composition (what you use now) does not make much sense in this case.
abstract class Animal
{
protected int numberOfLegs = 4; // default number of legs
public int NumberOfLegs { get { return numberOfLegs; } }
public Animal(int legs)
{
numberOfLegs = legs; // initialize number of legs
}
}
All concrete animals then derive from this class.
class Snake : Animal
{
public Snake() : base(0) // specify that number of legs is 0
{
}
}
The base(0) is a call to a base class constructor, so you are calling Animal(int legs) with an argument 0.
Do it like this:
abstract class Animal
{
private readonly int numberOfLegs;
protected Animal(int nrLegs = 4)
{
numberOfLegs = nrLegs;
}
public int returnNumberOfLegs()
{
return numberOfLegs;
}
}
class Snake : Animal
{
public Snake() : base(0)
{
}
}