Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#基类到子类的泛型继承_C#_Oop_Generics_Inheritance - Fatal编程技术网

c#基类到子类的泛型继承

c#基类到子类的泛型继承,c#,oop,generics,inheritance,C#,Oop,Generics,Inheritance,我有以下基类: public abstract class BaseClass<T> where T : IComparable { } 公共抽象类基类,其中T:IComparable { } 这个儿童班: public class ChildClass<T> : BaseClass<int> { } 公共类子类:基类 { } 在程序的不同位置,我有以下代码: List<BaseClass<IComparable>>

我有以下基类:

public abstract class BaseClass<T>  where T : IComparable
{

}
公共抽象类基类,其中T:IComparable
{
}
这个儿童班:

public class ChildClass<T> : BaseClass<int>
{

}
公共类子类:基类
{
}
在程序的不同位置,我有以下代码:

  List<BaseClass<IComparable>> objectList= new List<BaseClass<IComparable>>();
  ChildClass<int> childObject= new ChildClass<int>();
  ChildClass<double> childObject2= new ChildClass<double>()
  //both int and double are IComparable


//the bellow code dosent compile, it syas it cannot be casted, i dont understand why becuse they are his child class:
  objectList.Add(childObject);
  objectList.Add(childObject2); 
List objectList=new List();
ChildClass childObject=新的ChildClass();
ChildClass childObject2=新的ChildClass()
//int和double都是i可比较的
//下面的代码是编译的,因为它不能被转换,我不明白为什么,因为它们是他的子类:
objectList.Add(childObject);
objectList.Add(childObject2);

我不确定您需要该列表做什么,但正如您在评论中所说,这是一个问题。如果您需要找到一种基于列表中某类值或某组值获取子类的通用方法,您仍然可以这样做。虽然,这是一个回合,也许不是最好的解决方案

大概是这样的:

private void Main()
{
    var values = new List<IComparable>();

    values.Add(10);
    values.Add(5.55D);

    foreach (var value in values) {
        Console.WriteLine(value); // The value
        var childClass = BuildChild(value);
        Console.WriteLine(childClass.GetType().FullName); // The type
        // Using dynamic will work
        ((dynamic)childClass).DoWork((dynamic)value);
    }
}

private static object BuildChild(IComparable value)
{
    if (value == null)
        throw new ArgumentNullException(nameof(value));

    Type valueType = value.GetType();
    Type childClassType = typeof(ChildClass<>).MakeGenericType(valueType);
    return Activator.CreateInstance(childClassType);
}

// Define other methods and classes here
public abstract class BaseClass<T> where T : IComparable
{
}

public class ChildClass<T> : BaseClass<T> where T : IComparable
{
    public void DoWork(T value) {
        Console.WriteLine(value.GetType().FullName);
    }
}
private void Main()
{
var值=新列表();
增加(10);
加上(5.55D);
foreach(值中的var值){
Console.WriteLine(值);//值
var childClass=BuildChild(值);
Console.WriteLine(childClass.GetType().FullName);//类型
//使用dynamic将起作用
((动态)子类).嫁妆((动态)值);
}
}
私有静态对象BuildChild(IComparable值)
{
如果(值==null)
抛出新ArgumentNullException(nameof(value));
类型valueType=value.GetType();
类型childClassType=typeof(ChildClass)。MakeGenericType(valueType);
返回Activator.CreateInstance(childClassType);
}
//在此处定义其他方法和类
公共抽象类基类,其中T:IComparable
{
}
公共类ChildClass:基类,其中T:IComparable
{
公共无效工作(T值){
Console.WriteLine(value.GetType().FullName);
}
}
请注意,因为您使用反射来解析类型,所以此方法比使用预实例化实例时慢一点。我不确定您在反射和动态调用方面的经验,所以这只是一个提醒

就像我说的,我不知道你需要这个做什么。。。或者为什么需要列表中的特定子类。这个解决方案是另一种方式,您可以通过在运行时动态生成所需的类来获得类似的功能


另一种选择是删除基类上的泛型约束,并使用反射来解析子类,或者只删除所有泛型约束,并可能通过方法级泛型解析类型。然而,由于不知道您需要什么,我无法帮助您找到最佳解决方案,因此这些只是想法。

我不确定您需要该列表做什么,但正如您在评论中所说,这是一个问题。如果您需要找到一种基于列表中某类值或某组值获取子类的通用方法,您仍然可以这样做。虽然,这是一个回合,也许不是最好的解决方案

大概是这样的:

private void Main()
{
    var values = new List<IComparable>();

    values.Add(10);
    values.Add(5.55D);

    foreach (var value in values) {
        Console.WriteLine(value); // The value
        var childClass = BuildChild(value);
        Console.WriteLine(childClass.GetType().FullName); // The type
        // Using dynamic will work
        ((dynamic)childClass).DoWork((dynamic)value);
    }
}

private static object BuildChild(IComparable value)
{
    if (value == null)
        throw new ArgumentNullException(nameof(value));

    Type valueType = value.GetType();
    Type childClassType = typeof(ChildClass<>).MakeGenericType(valueType);
    return Activator.CreateInstance(childClassType);
}

// Define other methods and classes here
public abstract class BaseClass<T> where T : IComparable
{
}

public class ChildClass<T> : BaseClass<T> where T : IComparable
{
    public void DoWork(T value) {
        Console.WriteLine(value.GetType().FullName);
    }
}
private void Main()
{
var值=新列表();
增加(10);
加上(5.55D);
foreach(值中的var值){
Console.WriteLine(值);//值
var childClass=BuildChild(值);
Console.WriteLine(childClass.GetType().FullName);//类型
//使用dynamic将起作用
((动态)子类).嫁妆((动态)值);
}
}
私有静态对象BuildChild(IComparable值)
{
如果(值==null)
抛出新ArgumentNullException(nameof(value));
类型valueType=value.GetType();
类型childClassType=typeof(ChildClass)。MakeGenericType(valueType);
返回Activator.CreateInstance(childClassType);
}
//在此处定义其他方法和类
公共抽象类基类,其中T:IComparable
{
}
公共类ChildClass:基类,其中T:IComparable
{
公共无效工作(T值){
Console.WriteLine(value.GetType().FullName);
}
}
请注意,因为您使用反射来解析类型,所以此方法比使用预实例化实例时慢一点。我不确定您在反射和动态调用方面的经验,所以这只是一个提醒

就像我说的,我不知道你需要这个做什么。。。或者为什么需要列表中的特定子类。这个解决方案是另一种方式,您可以通过在运行时动态生成所需的类来获得类似的功能


另一种选择是删除基类上的泛型约束,并使用反射来解析子类,或者只删除所有泛型约束,并可能通过方法级泛型解析类型。但是,由于不知道您需要什么,我无法帮助您找到最佳解决方案,因此这些只是想法。

您需要的是类中没有的,但接口中有。但是,如果泛型类型仅用作属性(只读)和方法(返回类型,但不是参数)的输出,则只能使其协变。另一个选项是使泛型类型匹配然后找到一个解决方案,然后将该解决方案移植到您的列表场景中(我的评论中的代码示例不起作用,但这基本上是您在调用
Add
)时尝试执行的操作)@grek40
BaseClass item=new ChildClass()与列表不起作用的原因相同。@Carson是的,它基本上是一个提示,如何将手头的问题简化为其最小形式(MCVE*hint*)您想要的是类不可用,但接口可用。但是,如果泛型类型仅用作p的输出,则只能使其协变