Casting generic parameter to subclass - c#

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]);
}

Related

Enforcing generic interface childs type

I have a generic interface (MyInterface<T>), which is implemented by the class ChildA in the example below:
public interface MyInterface<T>
{
MyObj<T> GetObj(); // Irrelevant
}
class ChildA : MyInterface<ChildA>
{
// Irrelevant:
MyObj<ChildA> GetObj() {
return new MyObj<ChildA>();
}
}
This works, but I need to make sure that <T> always has the type of the implementing class, so in this case T should always be of type ChildA, because it is implemented by ChildA.
Another correct implementation could be this, for example:
class ChildB : MyInterface<ChildB> { ... }
But currently, this incorrect implementation is also possible, while it should not be:
class ChildA : MyInterface<ChildB> { ... }
Is there a way to enforce this?
You cannot enforce a generic type argument to be constrained to the implementing type.
The available type constraints are the following:
where T : struct
where T : class
where T : new()
where T : <base class name>
where T : <interface name>
where T : U
There is nothing like where T : self in C#. Actually, it wouldn't even make sense, because such a thing cannot be meaningfully enforced. Besides, it wouldn't fit at all into the covariance/contravariance concepts and would be weird to inherit from, in general.
The closest thing you can do is this:
public interface IMyInterface<T> where T : IMyInterface<T>
{
MyObj<T> GetObj();
}
Why it wouldn't make sense
Let's say you could do this:
public interface IMyInterface<T> where T : self // this syntax does not exist in C#
{
MyObj<T> GetObj();
}
Now all implementing types would have to use themselves as the type argument. But you could still do this:
public class ChildC<T> : IMyInterface<T> where T : self
{
/* ... */
}
Which would go around your restriction.
Is there a way to enforce this?
Well, not with generic constraints. You can do that with reflection though i'd vote against it :
public abstract class BaseChild<T> : MyInterface<T>
{
protected BaseChild()
{
if (typeof(T) != this.GetType())
{
throw new InvalidOperationException(string.Format(
"Type {0} is not supported as valid type parameter for type {1}",
typeof(T).Name, this.GetType().Name));
}
}
}
Example :
class ChildA : BaseChild<int> { }
// Bang! throws
var instance = new ChildA();
.
class ChildB : BaseChild<ChildB> { }
// Ok here
var instance = new ChildB();
You cannot do this but you can create your own control comparing the generic type of the interface and the type of your class. See the example:
class ChildA : MyInterface<ChildB>
{
public ChildA()
{
this.ValidateGenericType();
}
public MyObj<ChildB> GetObj()
{
return new MyObj<ChildB>();
}
protected void ValidateGenericType()
{
//throws an Exception because ChildB is different of ChilA
if (this.GetType().Name != this.GetType().GetInterfaces()[0].GetGenericArguments()[0].Name)
{
throw new Exception("The generic type must be of type ChildA.");
}
}
}
It seems that you should use extension methods instead of enforcing some interface for this purpose
public interface ISomeInterface {}
public class Child: ISomeInterface {}
public class OtherChild : ISomeInterface { }
public static class MyInterfaceExtensions
{
public static MyObj<T> GetMyObj<T>(this T child) where T : ISomeInterface
{
return new MyObj<T>();
}
}
public static class Test
{
public static void RunTest()
{
var child = new Child();
var otherChild = new OtherChild();
MyObj<Child> myObj = child.GetMyObj();
MyObj<OtherChild> myOtherObj = otherChild.GetMyObj();
}
}

Access static method of generic parameter

I currently have something like this:
abstract class BaseClass {
public abstract string title();
}
class Derived1 : BaseClass {
public override string title() { return "D1"; }
}
class Derived2 : BaseClass {
public override string title() { return "D2"; }
}
class Receiver<T> where T : BaseClass {
private T obj;
public string objTitle() { return obj.title(); }
}
The problem I am running into is that, if obj is null, objTitle throws a null reference exception. I can guarentee in this case that title will always return the same string for a given derived type; is there any way to make Receiver able to access it on the generic parameter T? My instinct is to use a static, but I don't know of any way to make a static visible to the Reciever; there's no way to make a base class or constraint specifying it.
You could use reflection to call a static method on the type, or if the value is actually a constant, you could also instantiate a new instance if there isn't an instance yet.
class Receiver<T> where T : BaseClass, new() {
private T obj;
public string objTitle() { return (obj ?? new T()).title(); }
}
What I would do is construct the T immediately and drop the if
class Receiver<T> where T : BaseClass, new() {
private T obj = new T();
public string objTitle() { return obj.title(); }
}
In C# you can't override static methods. From your design I can see that "title" is independent with an instance of BaseClass/Derived1/Derived2. Adding an instance method title() doesn't make sense here. I recommend you design these classes like this: (I renamed the classes to make it easy to understand)
abstract class MessageBase { }
class TextMessage : MessageBase { }
class ImageMessage : MessageBase { }
class Receiver<T> where T : MessageBase
{
public string GetMessageTitle()
{
if (typeof(T) == typeof(TextMessage)) return "Text";
else if (typeof(T) == typeof(ImageMessage)) return "Image";
return "Default";
}
}

Return a subclass of abstract return type?

My project is structured the following way:
// Abstract class
public abstract class Job
{
public abstract JobResult Run();
}
public abstract class JobResult { }
// Concrete implementer
public class Job1 : Job
{
public override Job1Result Run() { }
}
public class Job1Result : JobResult { }
Each concrete job inherits from Job and implements the method Run which returns a concrete class of JobResult.
However when I do this I get the compiler error:
Job1.Run()': return type must be JobResult to match overridden member
Job.Run()
Is it really not possible to return an inheriting object of the return type when overriding an abstract method?
This is the whole concept of inheritance. Returning parent classes is considered a feature here. Nothing stops you however from returning a Job1Result in Job1
public JobResult Run()
{
return new Job1Result();
}
Then the caller of Job1.Run() will have to know the correct return type and cast it to access Job1Result methods which are specific to that class
You could make Job generic:
public abstract class Job<TResult> where TResult : JobResult
{
public abstract TResult Run();
}
public class Job1 : Job<Job1Result>
{
public override Job1Result Run()
{
//
}
}
Here is an example, I hope it can help you.
public interface IEvent
{
Type GetEventType();
}
public abstract class AEvent<A>: IEvent where A: struct
{
public Type GetEventType()
{
return typeof (A); // return sub struct type
}
}

Array co-variance in C# generic list

I have an example where I want an abstract class interface to return something like this
abstract class AnimalProcessor {
public abstract IList<Animal> ProcessResults();
}
Then the concrete examples
class GiraffeProcessor : AnimalProcessor {
public override IList<Animal> ProcessResults() {
return new List<Giraffe>();
}
}
class LionProcessor : AnimalProcessor {
public override IList<Animal> ProcessResults() {
return new List<Lion>();
}
}
The problem is that the concrete classes need to have the same signature to override the ProcessResults() method so they need to return an IList<Animal>, however the ACTUAL data I want to return is an IList<Lion>, IList<Giraffe> etc, but then the calling code has to do
GiraffeProcessor processor = new GiraffeProcessor();
IList<Animal> results = processor.GetResults();
Which does not give me an Ilist which is what I want.
Problems
1) Above code does not compile. The giraffeProcessor has to return a concrete List<Animal>, you can populate it with Giraffe objects but the object type you construct to return has to be List<Animal>. Not ideal.
2) When you return the results, you can only get an IList<Animal>, not IList<Giraffe>. I have tried casting explicitly to IList<Giraffe> with
IList<Giraffe> results = (IList<Giraffe>) processor.GetResults();
which gives a runtime error, presumably because the object returned is NOT an IList<Giraffe>, it is an IList<Animal> which CONTAINS Giraffe objects.
Can anyone suggest what I am doing wrong here with my design as Im a bit stumped as to the best way to accomplish this.
How about:
abstract class AnimalProcessor<T> where T : Animal {
public abstract IList<T> ProcessResults();
}
class GiraffeProcessor : AnimalProcessor<Giraffe> {
public override IList<Giraffe> ProcessResults() {
return new List<Giraffe>();
}
}
class LionProcessor : AnimalProcessor<Lion> {
public override IList<Lion> ProcessResults() {
return new List<Lion>();
}
}
You could resolve this by declaring AnimalProcessor with a generic type constraint, e.g.
public abstract class AnimalProcessor<T> where T : Animal
{
public abstract IList<T> ProcessResults();
}
If that doesnt work, you could use the LINQ Cast operator, for example:
public class GiraffeProcessor : AnimalProcessor
{
public override IList<Animal> ProcessResults()
{
return new List<Giraffe>().Cast<Animal>();
}
}
Or, store the list internally as Animal but add Giraffe's to it, e.g.
public class GiraffeProcessor : AnimalProcessor
{
private List<Giraffe> _innerList = new List<Giraffe>();
public override IList<Animal> ProcessResults()
{
return new List<Animal>(innerList ); }
}
Best regards,
If you are using C# 4.0, you can ask yourself whether the processor should return IEnumerable<T> rather than IList<T>. If the answer is "yes", then you can profit from covariance:
abstract class AnimalProcessor {
public abstract IEnumerable<Animal> ProcessResults();
}
class GiraffeProcessor : AnimalProcessor {
public override IEnumerable<Animal> ProcessResults() {
return new List<Giraffe>();
}
}
class LionProcessor : AnimalProcessor {
public override IEnumerable<Animal> ProcessResults() {
return new List<Lion>();
}
}
You have a couple of advantages here. First, you could implement these as iterator blocks:
class GiraffeProcessor : AnimalProcessor {
public override IEnumerable<Animal> ProcessResults() {
yield break;
}
}
Second, and less trivially, you allow the client code to decide what kind of collection to dump the animals into -- if any. For example, consider that the consumer might want a LinkedList<Animal>:
var animals = new LinkedList<Animal>(animalProcessor.ProcessResults());
Or consider that the client might need only to iterate the sequence:
foreach (var animal in animalProcessor.ProcessResults())
{ /*... do something ...*/ }
In either case, if you were using a ToList() call in ProcessResults, you'd be creating a list for nothing. If the consumer really wants a List<Animal>, that can be accomplished very easily:
var animals = new List<Animal>(animalProcessor.ProcessResults());
Finally, you can also benefit from the generic approach, even if you change the interface type of the method's return value:
abstract class AnimalProcessor<T> where T : Animal {
public abstract IEnumerable<T> ProcessResults();
}
class GiraffeProcessor : AnimalProcessor<Giraffe> {
public override IEnumerable<Giraffe> ProcessResults() {
yield break;
}
}
class LionProcessor : AnimalProcessor<Lion> {
public override IEnumerable<Lion> ProcessResults() {
return Enumerable.Empty<Lion>();
}
}

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