Reputation: 1021
My problem is for some reason, I can't use derived class as the base when I pass it through a generic.
Let's suppose the below code to describe the idea
public class Person
{
public virtual bool IsGood { get; }
}
public class GoodPerson : Person
{
public override bool IsGood { get; } = true;
}
public class BadPerson : Person
{
public override bool IsGood { get; } = false;
}
public class Case<T>
{
public T PersonType { get; set; }
}
public class TypeReflector
{
public Person Reflect(Case<Person> person)
{
if (person.PersonType.IsGood)
return (GoodPerson)person.PersonType;
return (BadPerson)person.PersonType;
}
}
and called as below:
var reflector = new TypeReflector();
var result = reflector.Reflect(new Case<GoodPerson>());
why the method Reflect
can't be called with Case<GoodPerson>
.
but it possible without the Case
as below:
public Person Reflect(Person person)
{
if (person.IsGood)
return (GoodPerson)person;
return (BadPerson)person;
}
Upvotes: 4
Views: 169
Reputation: 6159
Since Case<Person>
is not the same type as Case<GoodPerson>
Much like..
Case<int>
is not the same type like Case<string>
Your reflector expected a strong type Case<Person>
but you're providing it a different strong type Case<GoodPerson>
(so this is like providing Case<string>
to a method which expects Case<int>
)
To make it work, make your reflector accept Case where T is a person or derived class of a person like this:
public class TypeReflector
{
public Person Reflect<T>(Case<T> person) where T:Person
{
return person.PersonType;
}
}
But below is what I think you really want to achieve, getting an instance of a type based on properties supplied in descriptor type. A type Person
once instantiated cannot be "elevated" to GoodPerson
instance without another new
keyword somewhere.. (btw, the opposite is possible, creating a GoodPerson
and casting to the more basic Person
class)
using System;
namespace ConsoleApp25
{
class Program
{
static void Main(string[] args)
{
var personDescriptor = new PersonDescriptor { IsGood = true };
var resultPerson = personDescriptor.CreateInstance();
Console.WriteLine(resultPerson.IsGood);
Console.WriteLine(resultPerson.GetType().Name);
Console.ReadLine();
}
}
public class PersonDescriptor
{
public bool IsGood { get; set; }
public Person CreateInstance()
{
if (IsGood)
return new GoodPerson(); //create new instance!
return new BadPerson(); //create new instance!
}
}
public abstract class Person
{
public abstract bool IsGood { get; }
}
public class GoodPerson : Person
{
public override bool IsGood { get; } = true;
}
public class BadPerson : Person
{
public override bool IsGood { get; } = false;
}
}
Upvotes: 4