Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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#_Inheritance_Abstract Class - Fatal编程技术网

C# 在实现抽象方法时更改参数类型

C# 在实现抽象方法时更改参数类型,c#,inheritance,abstract-class,C#,Inheritance,Abstract Class,是否有某种方法可以将抽象类型定义为抽象方法中的参数,并且当该方法在派生类中实现时,您可以将该方法的类型更改为接受派生类型 代码: 在我看来,这是有道理的。一个抽象类,指示派生类必须实现某个方法,但它们可以更改作为参数传入的对象的类型,只要它来自同一继承链 最后,我做的是从抽象类中删除抽象方法AddProduct,而只是在派生类中实现它,但是以后其他类就没有契约,它们必须创建自己的AddProduct实现。而且感觉不对 我希望这是有道理的。抱歉,如果这是一个重复的问题,但我无法通过搜索找到任何东西

是否有某种方法可以将抽象类型定义为抽象方法中的参数,并且当该方法在派生类中实现时,您可以将该方法的类型更改为接受派生类型

代码:

在我看来,这是有道理的。一个抽象类,指示派生类必须实现某个方法,但它们可以更改作为参数传入的对象的类型,只要它来自同一继承链

最后,我做的是从抽象类中删除抽象方法
AddProduct
,而只是在派生类中实现它,但是以后其他类就没有契约,它们必须创建自己的
AddProduct
实现。而且感觉不对

我希望这是有道理的。抱歉,如果这是一个重复的问题,但我无法通过搜索找到任何东西

谢谢,

bgs264

不,这是不可能的:假设您正在调用类
a
的变量
addProduct
,该变量指向类
C
的实例,传递的对象是
ProductBase
,但不是
SomeProduct
。传递的实例无法转换为
SomeProduct
,这就是为什么它不会首先编译的原因

最接近这一点的是使用泛型的解决方案:

public abstract class A<T>
    where T : ProductBase
{
    protected abstract void addProduct(T p);

}
public abstract class A<T> where T : ProductBase
{
    protected abstract void addProduct(T p);
}

public class C : A<SomeProduct>
{
    protected override void addProduct(SomeProduct p)
    {
        // ...
    }
}

但是,通常只有当类的某些用户可以知道泛型类型而其他用户不知道时,才需要这样的解决方案。

您可以将
类设置为泛型,并在
addProduct
方法中使用泛型参数:

public abstract class A<TProduct> where TProduct : ProductBase 
{
    protected abstract void addProduct(TProduct p);
}

public class B : A<ProductBase>
{        
    protected override void addProduct(ProductBase p)
    {
    }
}

public class C : A<SomeProduct>
{
    protected override void addProduct(SomeProduct p)
    {
    }
}
公共抽象类A,其中TProduct:ProductBase
{
受保护的抽象产品(t产品p);
}
B级:A级
{        
受保护的覆盖无效添加产品(ProductBase p)
{
}
}
公共C类:A
{
受保护的覆盖无效添加产品(SomeProduct p)
{
}
}
坦白地说,对于实现代码,我只需要一个演员阵容。我唯一能让这句话“漂亮”的是,如果它影响了公众:

protected override void addProduct(ProductBase p)
{
    SomeProduct prod = (SomeProduct)p;
    // ...
}
有一个选项是泛型,我不像我自己那样

public abstract class A<T>
    where T : ProductBase
{
    protected abstract void addProduct(T p);

}
public abstract class A<T> where T : ProductBase
{
    protected abstract void addProduct(T p);
}

public class C : A<SomeProduct>
{
    protected override void addProduct(SomeProduct p)
    {
        // ...
    }
}

@bgs264注意:这样做的一个大问题是您失去了
A
的抽象。例如,不能有
列表
,也不能有
a=SomeFactoryMethod()@bgs264:这样做时,请确保您确实需要抽象类。如果现在不指定
TProduct
,就不能调用
addProduct
,即使您只想拥有
a
类型的变量。参考我的解决方案中关于这个问题的评论。感谢两位的评论,我会将它们都考虑在内,这对我来说是一个学习曲线!)谢谢你的回答和解释,我很感激。我要走泛型的路线。我理解你说的,但我更喜欢类型安全,即C的实例只能将SomeProduct传递给addProduct,而不能传递另一个碰巧也继承了ProductBase的类型。但再次感谢
public abstract class A<T> where T : ProductBase
{
    protected abstract void addProduct(T p);
}

public class C : A<SomeProduct>
{
    protected override void addProduct(SomeProduct p)
    {
        // ...
    }
}
public abstract class A
{
    protected void addProduct(ProductBase p) { addProductImpl(p);}
    protected abstract void addProductImpl(ProductBase p);
}

public class C : A
{
    new protected void addProduct(SomeProduct p) { addProductImpl(p);}
    protected override void addProductImpl(ProductBase p)
    {
        SomeProduct prod = (SomeProduct) p;
        // ...
    }
}