C# dynamically instantiate Type from Enum - c#

I am a C# beginner. I hope you have patience with me. Lets say I have an enum
public enum Dogs
{
Terrier,
Poodle,
Pitbull,
}
and some dog classes
public class Terrier {
}
public class Poodle {
}
public class Pitbull {
}
And I for some reason want to instantiate each of the classes dynamically from their types (enum values),
foreach(Dogs d in Enum.GetValues(typeof(Dogs)))
{
// d myDog = new d();
// "...is a variable but is used like a type"
}
I have also tried with
var myDog = Activator.CreateInstance(d);
// "...cannot convert from namespace.Dogs to System.Type"

If you really want it:
(typeof(Dogs)).Assembly.CreateInstance(d.ToString());

Don't use an enum for that. A much saner solution is an array of Types:
private static Type[] dogs =
{
typeof(Terrier),
typeof(Poodle),
typeof(Pitbull),
}
Then you can still go over them all:
foreach (Type type in dogs)
{
Object dog = Activator.CreateInstance(type);
}
Though unless you're only using .ToString() on it, you might want to give those classes a common interface or superclass to inherit (as rfmodulator also said in his answer) so you can actually call functions on the resulting objects. If all three inherit from a Dog superclass, which makes them share a common Bark() method, you can at least do something like this:
public abstract class Dog
{
String Bark();
}
public class Terrier : Dog
{
public override String Bark() { return "Woof!"; }
}
public class Poodle : Dog
{
public override String Bark() { return "Yap"; }
}
public class Pitbull : Dog
{
public override String Bark() { return "Whuff!"; }
}
...so you can actually get something useful out of your instantiated objects:
foreach (Type type in dogs)
{
Dog dog = (Dog)Activator.CreateInstance(type);
Console.WriteLine(dog.Bark());
}
The only slight downside to this method, from a design perspective, is that there's no way to enforce that only sub-types of Dog can be put in the Type[] dogs array; technically, any type object can be put in there. So that's the programmer's responsibility to not mess that up.

Dogs.Terrier is a different thing than Terrier.
Here is how you could do something like you're describing:
For simplicity, I'm going to make all the classes implement a common interface, IDog:
public interface IDog { }
public class Terrier : IDog
{
}
public class Poodle : IDog
{
}
public class Pitbull : IDog
{
}
Now we can do this:
IDog dog;
foreach (Dogs d in Enum.GetValues(typeof(Dogs)))
{
switch (d)
{
case Dogs.Terrier:
dog = new Terrier();
break;
case Dogs.Poodle:
dog = new Poodle();
break;
case Dogs.Pitbull:
dog = new Pitbull();
break;
default:
throw new Exception("no such dog!");
}
Debug.WriteLine($"dog is {dog.GetType()}");
}

Related

Is it possible to restrict the type of variable passed to a .NET method to not be a derived class?

Can i constrain the type that is passed to my method in a way that catches this type of error when compiling instead of running?
My current code looks like this:
void Main()
{
var dog = new Dog();
SaveAnimal(dog);
}
void SaveAnimal(Animal animal) {
var isAnimal = animal.GetType().UnderlyingSystemType == typeof(Animal);
Debug.Assert(isAnimal, "You can not save dogs!");
}
class Animal {
public int Legs { get; set; }
}
class Dog : Animal {
public int TailLength { get; set; }
}
No, there is no way in the language to statically catch this as a usage error.
You can assert this at runtime as you are doing it already. It's against the spirit of inheritance, though, because a fundamental assumption is that derived types must substitute for the base type (the Liskov substitution principle).
Maybe you can make the animal save itself by giving Animal a new method abstract void Save(). Then, each animal decides what to do. Dog can then throw a NotSupportedException.
Yes, but only with a workaround using generics and interfaces.
What you would need to do is to declare 3 interfaces
public interface ISaveAbleBase { }
public interface ISaveAble : ISaveAbleBase{ }
public interface INotSaveAble : ISaveAbleBase { }
Now you need to give your Animal class a generic parameter and constraint it to be of type ISaveAbleBase.
class Animal<T> where T: ISaveAbleBase
{
public int Legs { get; set; }
}
This way you can now specify in the derived classes wether they can or cannot be saved:
class Dog : Animal<INotSaveAble>
{
public int TailLength { get; set; }
}
Then you could make your method generic and constrain the type only to aminals that can be saved
void SaveAnimal<T>(T animal) where T: Animal<ISaveAble>
Now the result looks the following way:
void Main()
{
var dog = new Dog();
SaveAnimal(dog); // does not compile
Animal<ISaveAble> generalAnimal = new Animal<ISaveAble>();
SaveAnimal(generalAnimal); // compiles
}
Disclaimer: this construct would also allow you to have a general Animal that cannot be saved:
Animal<INotSaveAble> generalAnimalNotSave = new Animal<INotSaveAble>();
SaveAnimal(generalAnimalNotSave); // does not compile
PS. This answer is inspired by this post
There is no standard way how to do this, but there is a simple (and stupid) workaround.
using System.Diagnostics;
namespace Test
{
internal static class Program
{
private static void Main()
{
var dog = new Dog();
SaveAnimal(dog);
}
private static void SaveAnimal(Animal animal)
{
var isAnimal = animal.GetType().UnderlyingSystemType == typeof(Animal);
Debug.Assert(isAnimal, "You can not save dogs!");
}
private static void SaveAnimal(ICanNotSave animal)
{
Debug.Fail("Can not save");
}
}
internal class Animal
{
public int Legs
{
get; set;
}
}
internal interface ICanNotSave
{
}
internal sealed class Dog : Animal, ICanNotSave
{
public int TailLength
{
get; set;
}
}
}
When you have two SaveAnimal method, where one of for Animal and other is for a interface, that is implemented on all descendants that can not be saved, the compiler report a CS0121 error.
The call is ambiguous between the following methods or properties: 'Program.SaveAnimal(Animal)' and 'Program.SaveAnimal(ICanNotSave)'
Remember it is still possible to use the SaveAnimal method when you use it like this: SaveAnimal((Animal)dog)

Non-Interface methods [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have been reading up on programing to interfaces rather than implementation. One area I am not properly understanding is how to deal with non-interface methods. For example an interface IAnimal and a Cat class that implements it. My examples are in C# but I think it should also apply to other languages.
public interface IAnimal
{
void Eat();
}
public class Cat : IAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Meow()
{
return "meow";
}
}
From what I've read it seems like I should be trying to work with the interface rather than the cat implementation such as,
Main()
{
IAnimal cat = new Cat();
}
But this leaves me without access to my meow method as it is not a part of the IAnimal interface. Should I be creating another interface ICat which implements IAnimals and have Cat implement it? And does this mean that all methods should be an implementation from an interface or abstract class? Or am I doing something else here wrong.
Thanks for your help.
What you would do is you is have another interface that represent's speaking animals and either inherit from IAnimal or add it as a 2nd interface. Classes that have animals that speak implement the 2nd interface.
with a inherited interface.
public interface IAnimal
{
void Eat();
}
public interface ISpeakingAnimal : IAnimal
{
string Speak();
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
With a 2nd decorator interface
public interface IAnimal
{
void Eat();
}
public interface ISpeakable
{
string Speak();
}
public class Cat : IAnimal, ISpeakable
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
If you need the method not be Speak() but instead be Meow() you can use explicit interface implementations to expose the Speak() method only though that interface.
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
string ISpeakingAnimal.Speak()
{
return Meow();
}
public string Meow()
{
return "meow";
}
}
The point of an interface is to define behavior common to classes that implement that interface. You are correct in noting that defining cat like so:
IAnimal cat = new Cat();
leaves you unable to access methods in the Cat class that are not in IAnimal. So why is it encouraged to implement things in this way?
The answer is simple: it makes it very easy to change the code later on. For example, if we have a Dog class that implements IAnimal, like so:
public class Dog : IAnimal
{
// some methods
}
then we can very easily replace our Cat class with the Dog class, without having to change any other code. In other words, we can replace:
IAnimal cat = new Cat();
with
IAnimal dog = new Dog();
without having to change any other code in the entire program (besides the variable names). This is because defining Cat and Dog with respect to IAnimal forces them to only use methods found within IAnimal, though they may be implemented differently in Cat and Dog.
Of course, if you want to use something specific only to Cat or Dog, you will have to define the class explicitly, as mentioned by #Erick in his answer, like so:
Cat cat = new Cat();
In general, you should try to define as many common behaviors in the interface as possible, only explicitly casting to a certain class like Cat or Dog when absolutely necessary. This makes your code a lot more versatile and changeable.
If you need to access the method it would be necessary to make an explicit cast.
In this case it would be more interesting to leave your Meow() method more generic for other possible classes that could implement it:
public interface IAnimal
{
void Eat();
void Speak();
}
public class Cat : IAnimal
{
public void Eat() { }
public string Speak()
{
return "meow";
}
}
public class Dog : IAnimal
{
public void Eat() { }
public string Speak()
{
return "au";
}
}
My two cents on this topic is that it's true that you need to depend on abstractions (i.e. interfaces) rather than implementations.
BTW, doesn't this going too far? There's no need to define an interface for any class within your object model. Usually you define interfaces if you need to accept certain objects fulfilling a given contract.
For example, I wouldn't define IAnimal or ICat interfaces. Probably I would define an abstract class Animal and just a concrete class Cat.
If for some reason I need to accept living beings in some API that could eat I would define an interface like this:
public interface IFeedable
{
void Feed(Food food);
}
and if a living being can talk:
public interface ITalkative
{
void Talk(Food food);
}
Unless there's no feature/property/behavior that could be exclusive to animals, I would leave these interfaces as is.
public abstract class Animal : ITalkative, IFeedable
{
public Animal(AudioPlayer audioPlayer)
{
AudioPlayer = audioPlayer;
}
private AudioPlayer AudioPlayer { get; }
public abstract void Feed(Food food);
public void Talk()
{
// Probably you would want to load an animal sound library
// here, and later pass the audio player with the sound library
// already loaded
OnTalk(AudioPlayer.LoadLibrary("animals"));
}
protected abstract void OnTalk(AudioLibrary audioLibrary);
}
public sealed class Cat : Animal
{
public Cat(AudioPlayer audioPlayer) : base(audioPlayer)
{
}
public override void Feed(Food food)
{
if(food is Vegetable)
{
throw new NotSupportedException("MeeEEEEooW (=O ò.ó)=O!!");
}
else if(food is Meat)
{
// Proceed to eat this meat!
}
}
protected override void OnTalk(AudioLibrary audioLibrary)
{
audioLibrary.Play("sweet-cat");
}
}
And if somewhere you need to make an object to talk:
ITalkative talkative = some as ITalkative;
if(talkative != null)
{
talkative.Talk();
}
Or if you need to feed the object:
IFeedable feedable = some as IFeedable;
if(feedable != null)
{
feedable.Feed(new Vegetable());
}
As you can see, you don't define interfaces for everything, but just for those things that you need to handle inside some API and you don't care who can do some actions and/or own some data, but you just care about the object can do or exposes certain behaviors and data respectively.

Casting generic parameter to subclass

Please look at the code bellow:
public class BaseClass
{
}
public class SubClass : BaseClass
{
}
public class QueryClass
{
public TBaseClass[] QueryBase<TBaseClass>() where TBaseClass : BaseClass
{
throw new NotImplementedException();
}
public TSubClass[] QuerySub<TSubClass>() where TSubClass : SubClass
{
throw new NotImplementedException();
}
public TClass[] Query<TClass>() where TClass : BaseClass
{
if (typeof(TClass).IsSubclassOf(typeof(SubClass)))
{
return QuerySub<TClass>(); // there is error The type 'TClass' must be convertible to SubClass
}
return QueryBase<TClass>();
}
}
The question is how to implement Query method. If it is possible..
What you are trying to do is doing something like this:
public class Animal { }
public class Dog : Animal { }
public void HandleAnimal<T>() where T : Animal
{
}
public void HandleDog<T>() where T : Dog
{
}
When you have a reference to Animal in this case, there is no way of knowing what typeof animal it is. Even if the method returns true, in the context of your code it is still always an Animal and you can't handle a dog when all you know is that the type is an animal. If you were handling instances of objects inside the method you could potentially start casting or instansiating the subclass if you know that it is a subclass and then pass that through.
Ended up with reflection.
if (typeof(TClass).IsSubclassOf(typeof(SubClass)))
{
var method = typeof(QueryClass).GetMethod("QuerySub").MakeGenericMethod(typeof (TClass));
return (TClass[]) method.Invoke(this, new object[0]);
}

Can I hold a List<> of Object Types of the same descendant?

I need to hold a list of object types that are allowed to do certain actions.
Example Animal has 3 descendants Tiger, Human, Hippo
I want to allow only Tigers and Hippos to be held in zoo cages? I need a list of animal types.
I would love something better than List<Type>
This is just a simplified example. I don't like animals in cages..
edit
Since it's not clear. I want to hold object types in the list and not actual objects.
Example:
List<Type> types = new List<Type>();
types.Add(typeof(Hippo));
types.Add(typeof(Tiger));
This has the limit that a programmer can do types.Add(typeof(Human)) and this is what I wan't to dissallow.
edit2
Just to clarify my question. I want to be able to dynamically Register allowed types and not having consequent ifs as some answers bellow.
If you want a list of only certain types:
There isn't anything in generics that can support what you are asking for, so simply create a custom type that allows you to store Type types and have code at runtime for guarding against invalid entries:
public class CagedTypes
{
private readonly List<Type> _types;
public void Add(Type t)
{
if (t == typeof(Hippo) || t == typeof(Tiger))
_types.Add(t);
}
}
Although I can't see why you might need this.
Alternative if you want a list of only certain types:
Do the same as above, but include the interface below and change the add check to something like:
public void Add(Type t)
{
if (t.GetInterfaces().Contains(typeof(ICanBeHeldInZooCage)))
_types.Add(t);
}
You could also use attributes, as you can query a type for any attributes using the GetAttributes method.
If you wish to only have certain instances in a list:
Create a marker interface:
public interface ICanBeHeldInZooCage
That Tiger and Hippo implement (doesn't have to do anything), then you can have:
var cagedAnimals = new List<ICanBeHeldInZooCage>();
Approach1 - via interfaces:
public interface ICageable
{ }
public abstract class Animal
{}
public class Hippo : Animal, ICageable
{}
public class Human : Animal, ICageable
{}
public IEnumerable<Type> GetCageableAnimals()
{
return GetAssemblyTypes(assembly:typeof(Animal).Assembly)
.Where(type=>IsDerivedFrom(type, typeof(Animal)))
.Where(type=>ImplementsInterface(type,typeof(ICageable)));
}
Approach 2 - via attribute:
public class InCageAttribute : Attribute
{ }
public abstract class Animal
{}
[InCage]
public class Hippo : Animal
{}
public class Human : Animal
{}
public IEnumerable<Type> GetCageableAnimals()
{
return GetAssemblyTypes(assembly:typeof(Animal).Assembly)
.Where(type=>IsDerivedFrom(type, typeof(Animal)))
.Where(type=>MarkedByAttribute(type,typeof(InCageAttribute)));
}
UPDATE
IMPORTANT
Both these approaches provide only runtime check. having compilation check implementation would be better, but don't know for know how to achieve that.
UPDATE2
For dynamic registration:
public class CageRegistry
{
private List<Type> _allowedTypes = new List<Type>();
public IEnumerable<Type> AllowedTypes{get{return _allowedTypes;}}
public bool TryAdd(Type type)
{
if(ImplementsInterface(type, typeof(ICageable)))// for approach with attributes code is pretty similar
{
_allowedTypes.Add(type);
return true;
}
return false;
}
}
PS2
Sorry for not implemented methods like MarkedByAttribute, IsDerivedFrom and ImplementsInterface - I just don't have visual studio on current machine yet and don't remember api exactly.
How about an Interface?
public interface ICageable {}
public abstract class Animal {}
public class Hippo : Animal, ICageable {}
public class Tiger : Animal, ICageable {}
public class Human : Animal, ICageable {}
public class Ape : Animal {}
....
List<ICageable> ZooAnimals = new List<ICageable>{hippo, tiger, human};
(writing from a Planet of the Apes perspective)
and if you need the types themselves in a list, well types are instances of the Type type, so whatever you create it will be a collection of types. You could encapsulate is like this:
public class CageableTypesCollection :
{
private List<Type> _cageableTypes;
public CageableTypesCollection()
{
_cageableTypes = new List<Type>();
}
public RegisterType(Type t)
{
if (!typeof(ICageable).IsAssignableFrom(t))
throw new ArgumentException("wrong type of type");
_cageableTypes.Add(t);
}
public UnregisterType(Type t)
{
....
}
.....
}
I would use an interface to determine if an animal is a ZooAnimal
public class Animal
{
public string Name;
}
public class Tiger : Animal, IZooAnimal
{
}
public class Human : Animal
{
}
public interface IZooAnimal
{
//Some zoo animal properties
}
And then check if the animal is a Zoo Animal if (a is IZooAnimal) below is a zoo class which you could use.
public class Zoo
{
public List<IZooAnimal> AnimalsInZoo = new List<IZooAnimal>();
public void AddAnimal(IZooAnimal a)
{
AnimalsInZoo.Add(a);
}
}
EDIT:
Ok now to do this with types and constrain the types to a ZooAnimal I have made a generic zoo class which takes T where T is a ZooAnimal - you could have a list of ZooAnimals or a list of tigers in our case.
public class Zoo<T> where T : IZooAnimal
{
public List<Type> AnimalTypes = new List<Type>();
public void AddType(Type a)
{
if (typeof(T) == a)
AnimalTypes.Add(a);
}
}
This will add type Tiger to the AnimalsInZoo. Hope this works for you.
Zoo<IZooAnimal> cage = new Zoo<IZooAnimal>();
cage.AddType(typeof(Tiger));
cage.AddType(typeof(Human));
Human is animal, Tiger is animal that should be in zoo. So in your case I'd create one more base class for Tiger and Hippo.
public class AnimalInZoo : Animal {}
public class Tiger : AnimalInZoo {}
public class Hippo : AnimalInZoo {}
public class Human : Animal {}
You can create helper function AddInZoo(AnimalInZoo obj) to add in you List<Type> m_Zoo:
void AddInZoo(AnimalInZoo obj)
{
m_Zoo.Add(obj.GetType());
}
The other option:
public abstract class Animal
{
public abstract bool IsCagable { get; }
}
And let the nested classes to implement their behavior.
Later then, the some sort of Zoo class which is mostly presented in the answers in this topic, inside the method Add must do the check:
public sealed class ZooList : List<Animal> // I believe you need Animal, not Type
{
// ... some implementations ...
public override sealed void Add(Animal animal)
{
if (!animal.IsCagable)
// Prevent from adding.
}
}

Elegant Dynamic Type Casting

I'd appreciate your advice on the following:
I'm using polymorphism. I have a base class and 30 sub classes that inherit this base class. I'm up casting instances of these sub classes to the base class type so that they can be handled in a more generic fashion.
My question is this.
I need to access a public property that is specific to a particular sub class. Do I need to write a giant case statement where I check the type and down cast accordingly in order to access the property I need or is there a more elegant solution?
static void Main(string[] args)
{
animal slyvester = new cat();
animal lassie = new dog();
animal silver = new horse();
// Big ugly type checking code. If I have 30 types to check is there a better way?
if (slyvester.GetType() == typeof(cat)) {
Console.WriteLine(((cat)(animal)slyvester).PurrStrength);
}
else if(slyvester.GetType() == typeof(dog)) {
}
else if (slyvester.GetType() == typeof(horse))
{
}
Console.ReadLine();
}
}
public class animal {
}
public class cat : animal {
private string _purrStrength = "Teeth Shattering";
public string PurrStrength {
get { return _purrStrength; }
set { _purrStrength = value; }
}
}
public class dog : animal {
}
public class horse : animal {
}
You should consider an interface based approach. With interfaces, you define a set of operations (a contract by which implementers must conform) which your types must define. E.g, we could define a base interface, IAnimal
public interface IAnimal
{
string GetSound();
}
From which we can define some animal types:
public class Cat : IAnimal
{
public string GetSound()
{
return "Meow!";
}
}
public class Dog : IAnimal
{
public string GetSound()
{
return "Woof!";
}
}
Now, when we want to declare our animal, we declare it of type IAnimal:
IAnimal cat = new Cat();
IAnimal dog = new Dog();
Console.WriteLine(cat.GetSound());
Console.WriteLine(dog.GetSound());
You could go one step further, and specialise your animals:
public class Cat : IAnimal
{
public virtual string GetSound()
{
return "Meow!";
}
}
public class BigCat : Cat
{
public override string GetSound()
{
return "Roar!";
}
}
In the latter example, I can make a default implementation of the cat's GetSound method, and then override it for my big cat.
Interface based programming hides away the need to horrible type conversions, because an interface guarantees a set of operations that will be provided.
If you don't have to know the exact type of the passed object, you just need a property value in case it doesn't exist in the base type, but it may or may not exists in the actual type, you can use reflection:
static void Main(string[] args)
{
animal slyvester = new cat();
animal lassie = new dog();
animal silver = new horse();
DoSomething(slyvester);
DoSomething(lassie);
DoSomething(silver);
Console.ReadLine();
}
static void DoSomething(animal entity)
{
string INeedThisProperty = "PurrStrength";
Type type = entity.GetType();
PropertyInfo property = type.GetProperty(INeedThisProperty);
if (property != null && property.CanRead)
{
Console.WriteLine("Found: {0}", property.GetValue(entity, null));
}
}
If in precise moment of property access you dont't have any clue what type is it, somehow you have to figure out it.
Or, what I personaly would do, is try to create virtual functions/properties on base class that describes my child classes action in more generic way, override them in child classes with concrete implementation and after call that functions/properties using upper casted objects.
The answer is to use polymorphism. The idea is to introduce a method in the base interface or as in this case the base class. Then just call this method! The runtime will automagically delegate the call to the correct type.
Look at the modified implementation below:
public abstract class Animal
{
public abstract void OutputInterestingFact();
}
public class Cat : Animal {
private string _purrStrength = "Teeth Shattering";
public string PurrStrength {
get { return _purrStrength; }
set { _purrStrength = value; }
}
public override void OutputInterestingFact()
{
Console.WriteLine(PurrStrength);
}
}
public class Dog : Animal {
public override void OutputInterestingFact()
{
// Do stuff for dog here
}
}
public class Horse : Animal {
public override void OutputInterestingFact()
{
// Do stuff for horse here
}
}
I made the Animal into an abstract class. You could also make the OutputInterestingFact method virtual with an empty method body.
I've also renamed your classes to begin with an upper case letter. Make this a habit since this is practice in C# and other programmers will find your code easier to read.
Now, to use this just call the method.
slyvester.OutputInterestingFact();
Is that elegant enough?
Your code does not cover all the cases that I can think of, but just 2 possible solutions:
class Animal {
public abstract string PropertyValue { get; set; }
}
class Cat : Animal {
public override string PropertyValue {
get { return PurrStrength; }
set { PurrStrength = value; }
}
}
or, for multiple properties:
class Animal {
public virtual string[] GetPropertyValues() { return null; }
}
class Cat : Animal {
public override string[] GetPropertyValues() {
return new string[] { PurrStrength };
}
}

Categories

Resources