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();
Related
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.
I have created a simple test project to use a class as a custom List type and have a couple of questions regarding the use of different syntax when declaring variables.
I have a class called CustomerInfo which defines all the variables required to be stored for the customer information which will be added to a list as seen below:
protected string Firstname { get; set; }
protected string Surname { get; set; }
protected int Age
{
get
{
return Age;
}
set
{
if(value < 0)
{
throw new AgeException("Age cannot be a value below 0");
}
else
{
Age = value;
}
}
}
protected string Gender { get; set; }
Questions:
1) Why does the code below not allow me to access the protected variables in the CustomerInfo class even though I am inheriting the class?
class Program : CustomerInfo
{
static void Main(string[] args)
{
CustomerInfo custInfo = new CustomerInfo();
custInfo.Firstname = "Richard"; //not working
custInfo.Surname = "Smith"; //not working
List<CustomerInfo> custList = new List<CustomerInfo>();
custList.Add(custInfo);
}
}
2) When looking at Windows Forms applications they already contain an inheritence of Form in the code of any Form you create. If you have to inherit a class to access the protected variables & methods it has, how can you access the variables if each form already has an inheritance that you cannot remove?
Thanks
You are misunderstanding the purpose of inheritance. Inheritance is designed to represent a relationship between two objects where one is a more specialized version of the other. This is sometimes called an "is-a" relationship.
Consider the following class definitions:
class Fruit {}
class Apple : Fruit {}
class Banana: Fruit {}
In this case, Apple and Banana both inherit from Fruit to express the "is-a" relationship - a Banana is a Fruit. In object-oriented design, this allows you to write a method like this:
class Person
{
public void Eat(Fruit fruit) {}
{
// stuff goes here
}
}
The Eat method allows the Person class to eat anything that is a Fruit, including classes that derive from Fruit. So you can do the following:
Person person = new Person();
Apple apple = new Apple();
Banana banana = new Banana();
person.Eat(apple);
person.Eat(banana);
Compare this to the class definition you have written:
class Program : CustomerInfo
In the language of OOP, this says "a Program is a CustomerInfo." I don't think that's what you want. Using the protected keyword doesn't make sense here because your inheritance relationship doesn't make sense. If Program is supposed to be able to access CustomerInfo members, they should be declared public or internal.
The protected keyword is a member access modifier. A protected member
is accessible within its class and by derived class instances.
Source MSDN
CustomerInfo custInfo = new CustomerInfo();
custInfo.Firstname = "Richard"; //not working
custInfo.Surname = "Smith"; //not working
This code is not working because your custInfo's Firtsname and Surname are not accessible in the Program class. But you should be able to do the following, as your Program class is inherited from CustomerInfo :
Firstname = "Richard";
Surname = "Smith";
For the second question you can do something like the following:
Class1 : Form
{
// here will be your protected members
}
Class2 : Class1
I have this dog class:
public class Dog : IBarkable
{
public void Bark()
{
Console.WriteLine("Woof!");
}
}
and i have this human class:
public class Human : IBarkable
{
private Dog _myDog = new Dog();
public void Bark()
{
_myDog.Bark();
}
}
Is there any way that i won't have to implement each function explicitly?
somthing like this:
public class Human : IBarkable (_myDog)
{
private Dog _myDog = new Dog();
}
thanks!
Though there is no features for implementing delegating members in visual studio, resharper provides one.
You're looking for Generating Delegating Members of resharper.
From the logical point of view a Human can not bark. So deriving a human from this interface makes no sense. Instead you should provide at least a getter method returning your dog object.
If you are trying to expose a "pet" of the human, a more flexible and technically correct way would be to abstract the Bark method and make the human expose certain aspects of the "pet". As far as API design goes, it's not very intuitive to have a method "Bark" on a human object. Also to consider: what if the human as a cat, parrot, monkey, and an elephant for pets? In this case, your code as it is becomes difficult to maintain (which I suspect is why you want to "auto-implement" interface methods).
I would suggest a slight refactor of your code into something more like this:
public interface ISpeakingAnimal {
void Speak();
} // end interface IAnimal
public interface IHasPets {
List<ISpeakingAnimal> Pets {get; set;}
bool HasPets();
} // end interface IHasPets
public class Dog : ISpeakingAnimal {
public void Speak() {
Console.WriteLine("Woof");
}
} // end class Dog
public class Cat : ISpeakingAnimal {
public void Speak() {
Console.WriteLine("Meow");
}
} // end class Cat
public class Human : IHasPets {
public Human() {
Name = "The Doctor";
Pets = new List<ISpeakingAnimal>();
} // end constructor
public string Name {get; set;}
public List<ISpeakingAnimal> Pets {get; set;}
public bool HasPets() {
return Pets.Any();
} // end method HasPets
} // end class Human
//Somewhere in your executing code
Human person1 = new Human();
ISpeakingAnimal dog = new Dog();
ISpeakingAnimal cat = new Cat();
person1.Pets.Add(dog);
person1.Pets.Add(cat);
for(int i = 0; i<person1.Pets.Count; i++) {
person1.Pets[i].Speak();
} // end for loop
This encompases several SOLID software development practices, which you can read more about here if you're interested: http://www.blackwasp.co.uk/SOLID.aspx
This design allows you to add new types of pets at any point without having to make changes to Human, or the other animals. and you can add methods to human to interact with it's pets without changing the actual nature of what a human is (since we don't typically bark ;)).
Let me explain you in the following example what problem I'm solving:
class Animal {}
class Cat: Animal {}
class Dog : Animal { }
interface IAnimalHandler<in T> where T: Animal
{
void Handle(T animal);
}
class AnimalHandler :
IAnimalHandler<Cat>,
IAnimalHandler<Dog>
{
public void Handle(Cat animal)
{
Console.Write("it's a cat !");
}
public void Handle(Dog animal)
{
Console.Write("it's a dog !");
}
}
So now I want go through all animals and run appropriate handler like this:
var ah = new AnimalHandler();
var animals = new List<Animal> { new Cat(), new Dog() };
animals.ForEach(a => ah.Handle(a));
However this code would not work (Can not resolve method Hanler<>...) just because .NET compiler needs to know before compilation which type is used here, so what might be the best solution for this issue? In other words, I need to ask .NET compiler to take appropriate handler of type T for every instance of type T in run-time.
I do not want to use multiple if statements checking instance type.
UPDATE: Sorry for missing it, it seemed obvious to me, but now I understand it's not so obvious: AnimalHandler class contains logic not supposed to be part of domain objects Cat and Dog. Think about them as pure plain domain objects, I do not want them to know about any sort of handlers
You can use C# 4 dynamic to move the overload resolution step from compile-time to runtime:
var ah = new AnimalHandler();
var animals = new List<Animal> { new Cat(), new Dog() };
animals.ForEach(a => ah.Handle((dynamic)a));
To me it sounds like you could benefit from this pattern (implemented using StructureMap). Going from your original statement, "I need to ask .NET compiler to take appropriate handler of type T for every instance of type T in run-time" it might look something like this:
class Dog : Animal { }
class Cat : Animal { }
interface IHandler<T>
{
void Handle(T eval);
}
class DogHandler : IHandler<Dog>
{
public void Handle(Dog eval)
{
// do whatever
}
}
class CatHandler : IHandler<Cat>
{
public void Handle(Cat eval)
{
// do whatever
}
}
You could then configure StructureMap as per the linked article, and get the appropriate handler using:
var dogHandler = _container.GetInstance<IHandler<Dog>>(); // instance of DogHandler
var catHandler = _container.GetInstance<IHandler<Cat>>(); // instance of CatHandler
UPDATE:
To resolve these in a loop you could do something like this:
foreach (var animal in animals)
{
var concreteHandlerType = typeof(IHandler<>).MakeGenericType(animal.GetType());
var handler = _container.GetInstance(concreteHandlerType);
handler.Handle(animal);
}
I use this pattern in a fairly large system to accomplish the same goals (pure domain objects, handlers for logic that should not be inside those domain objects, simplified maintenance). It works well in a system where you want to have a separate handler class for each object.
Exactly your code, but using reflection:
var ah = new AnimalHandler();
var animals = new List<Animal> { new Cat(), new Dog() };
animals.ForEach(a => {
var method = ah.GetType().GetMethod("Handle", new Type[] {a.GetType()});
method.Invoke(ah,new object[] { a });
});
Why would you have specific handlers for each type of animal. Instead implementing multiple specific interfaces, just implement IAnimalHandler<T>, and just have a single Handle(T obj) method. If you then need type specific functionality you can handle it by calling typeof(obj) to get the specific type.
Here's an approach: Make an abstract method in Animal, something called "BeingHandled()" for example, and then all inheritors of Animal must provide their own implementation.
Then your AnimalHandler class would have a single Handle(Animal a) method:
class AnimalHandler
{
public void Handle(Animal a)
{
a.BeingHandled();
}
}
It doesn't matter which animal you pass to Handle() because anything that inherits from Animal must have proper implementation to work, and the compiler will know this because of the abstract method declaration within your Animal base class.
Since you are using .NET 4.0 take advantage of covariance/contravariance to inject a handler for your types.
interface IAnimal
{
string Name { get; set; }
}
class Dog : IAnimal
{
public string Name { get; set; }
}
class Cat : IAnimal
{
public string Name { get; set; }
}
interface IAnimalEvaluator<T>
{
void Handle(IEnumerable<T> eval);
}
class AnimalHandler : IAnimalHandler<T> where T : IAnimal
{
public void Handle(IEnumerable<T> eval)
{
foreach (var t in eval)
{
Console.WriteLine(t.Name);
}
}
}
List<Dog> dogs = new List<Dog>() { new Dog() { Name = "Bill Murray" } };
List<Cat> cats = new List<Cat>() { new Cat() { Name = "Walter Peck" } };
AnimalHandler <IAnimal> animalHandler = new AnimalHandler<IAnimal>();
animalEvaluator.Handle(dogs);
animalEvaluator.Handle(cats);
Use the visitor pattern and double dispatch. It works like this. The handler can handle different types of animals. Instead of letting the handler choose the right method, the animals chooses the right method. This is easy, since the animal always needs the same method ("his" method).
class Animal
{
string Name { get; set; }
abstract public Handle(IAnimalHandler handler);
}
class Cat : Animal
{
public overrides Handle(IAnimalHandler handler)
{
handler.Handle(this); // Chooses the right overload at compile time!
}
}
class Dog : Animal
{
public overrides Handle(IAnimalHandler handler)
{
handler.Handle(this); // Chooses the right overload at compile time!
}
}
interface IAnimalHandler
{
void Handle(Cat cat);
void Handle(Dog dog);
}
class AnimalHandler : IAnimalHandler
{
public void Handle(Cat cat)
{
Console.Write("it's cat {0}", cat.Name);
}
public void Handle(Dog dog)
{
Console.Write("it's dog {0}", dog.Name);
}
}
Now you can handle animals like this
IAnimalHandler handler = new AnimalHandler();
animals.ForEach(a => a.Handle(handler));
handler = new SomeOtherAnimalHandler();
animals.ForEach(a => a.Handle(handler));
I have something which should be easy to answer for most of your I think:
I have the following classes:
class One
{
string first;
}
class Two : One
{
string second;
}
Now I wanted to replace all One values of a Two value. So I tried the following:
One one = new One();
Two two = new Two();
two = (Two) one; // <= this seems to not work
So do I really have to implement a Method that copys all members of one to two?
One doesn't inherit from Two, and that is what is not working great.
Class inheritance doesn't mean to hide or to replace one class's property value, but that the derived class is a specialization of the base class it inherits from.
For example:
public class Cat {
}
public class Dog {
}
What do these two have in common?
They have four legs;
They are all animals;
They have hairs;
What do they not have in common?
A cat meows;
A dog barkles;
Let's revise our model by setting this in order.
public class Cat {
public bool HasHair { get { return true; } }
public int Legs { get { return 4; } }
public string Speaks { get { return "Meows"; } }
}
public class Dog {
public bool HasHair { get {return true; } }
public int Legs { get { return 4; } }
public string Speaks { get { return "Barkles"; } }
}
Now, to save you time and coding, what could we do? Generalize what both classes have in common? Alright! But how to make it so!?
public class Animal {
public bool HasHair { get { return true; } }
public int Legs { get { return 4; } }
public virtual string Speaks { get { return "Does a sound"; } }
}
// We can now inherit from Animal to write our Cat and Dog classes.
public class Cat : Animal {
public overrides string Speaks { get { return "Meows"; } }
}
public class Dog : Animal {
public overrides string Speaks { get { return "Barkles"; } }
}
And you can do:
Dog dog = new Dog();
dog.Legs; // Because Legs is an Animal property, and a Dog inherits from Animal, then Dog has a property called Legs, since it got it from his base class.
Now, we can do:
Animal pet = (Animal)(new Cat());
That said, you can typecast a Cat to an Animal, because it is an Animal! Now, you have to consider that your typecasted Cat will "do a sound", instead of "meowling", since by typecasting Cat to Animal, you're saying that you want to work with any Animal, as long as it is one. So both Cat and Dog are animals.
We could push our example even further by saying that not every animal has four legs, some doesn't have any, and others have only two. Then, we would have to generalize and to specialize accordingly.
In short: Yes
Like what was already said, One doesn't inherit from Two, so there's no "logical" default action to take here.
You should look into Conversion Operators. This'll let you still use the two=(Two) one syntax after defining an operator, like this(in the class def):
public static explicit operator Two(One o)
{
var t=new Two();
t.first=o.first;
t.second="default";//or whatever kind of default value you want
return t;
}
You can't cast a One as a Two because One does not inherit from Two. The other way around would work fine though (Two two = new One();)
In order to get a Two from a One you will have to create a new Two. You could have a method that copies all members of One to Two or you could have a constructor for Two that takes a One and sets the properties from there.
It is important to remember that one and two are just pointers in memory to an instance of an object.
If we were to write this out in plain English it would read something like this:
One one = new One();
Create a pointer in memory that refers
to an object of type One and label it
one, Then create an object of type One
and place it at the memory location
indicated by one.
two = (Two) one;
Replace the object referenced by two
with the object referenced by one, and
treat it as though it were an object
of type Two
Aside from the obvious typing problem you have, this will only replace the referenced object in memory, not copy the values from one to the other.
Yes, you have to implement a method that copies all members of one to two. Normally, you would make a constructor:
public Two(One one) {
this.first = one.first;
}
// Elsewhere ...
Two two = new Two(one);
Or if you want to copy over the values of an existing instance, you might do it with an instance method:
public void CopyValuesFrom(One one) {
this.first = one.first;
}
// Elsewhere ...
Two two = new Two();
two.CopyValuesFrom(one);