简体   繁体   English

带有继承的 C# 泛型

[英]C# generics with inheritance

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> .为什么不能使用Case<GoodPerson>调用方法Reflect but it possible without the Case as below:但没有Case是可能的,如下所示:

public Person Reflect(Person person)
{
    if (person.IsGood)
        return (GoodPerson)person;

    return (BadPerson)person;
}

Since Case<Person> is not the same type as Case<GoodPerson>由于Case<Person>Case<GoodPerson>类型Case<GoodPerson>
Much like..很像..
Case<int> is not the same type like Case<string> Case<int>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> )您的反射器需要一个强类型Case<Person>但您为它提供了一个不同的强类型Case<GoodPerson> (所以这就像将Case<string>提供给一个需要Case<int>

To make it work, make your reflector accept Case where T is a person or derived class of a person like this:为了让它工作,让你的反射器接受 Case 其中 T 是一个人或一个人的派生类,如下所示:

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)一旦实例化的类型Person不能在没有其他new关键字的情况下“提升”为GoodPerson实例..(顺便说一句,相反是可能的,创建一个GoodPerson并转换为更基本的Person类)

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM