Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# 列表<;界面实施>;vs列表<;BaseClassExtension>;_C#_.net - Fatal编程技术网

C# 列表<;界面实施>;vs列表<;BaseClassExtension>;

C# 列表<;界面实施>;vs列表<;BaseClassExtension>;,c#,.net,C#,.net,我有一个接口(IFoo)和另一个接口(IBar),其中包含一个列表,我的目标是实现IFoo(FooImp)并在IBar(BarImp)的实现中使用它。我知道接口不传输属性,您应该使用抽象基类,但我不知道如何实现这一点。以下是我的接口和实现,我知道这些接口和实现不起作用,但我以此为出发点: public interface IFoo { bool BoolOne { get; set; } } public interface IBar { List<IFoo> Fo

我有一个接口(IFoo)和另一个接口(IBar),其中包含一个
列表
,我的目标是实现IFoo(FooImp)并在IBar(BarImp)的实现中使用它。我知道接口不传输属性,您应该使用抽象基类,但我不知道如何实现这一点。以下是我的接口和实现,我知道这些接口和实现不起作用,但我以此为出发点:

public interface IFoo
{
    bool BoolOne { get; set; }
}

public interface IBar
{
    List<IFoo> FooList { get; }
}

/// <summary> Implements IFoo interface </summary>
public class FooImp : IFoo
{
    public bool BoolOne { get; set; } //required interface implementation
    public bool BoolTwo { get; set; } //new property
}

/// <summary>Implements IBar interface </summary>
public class BarImp : IBar //Error - does not implement
{
    public List<FooImp> FooList { get; private set; } //Error: "Does not match the expected type 'IFoo'". No suprise here
}
公共接口IFoo
{
bool BoolOne{get;set;}
}
公共接口IBar
{
列表傻瓜{get;}
}
///实现IFoo接口
公共类FooImp:IFoo
{
public bool BoolOne{get;set;}//必需的接口实现
public bool BoolTwo{get;set;}//新属性
}
///实现IBar接口
公共类BarImp:IBar//错误-未实现
{
公共列表愚人者{get;private set;}//错误:“与预期的类型'IFoo'不匹配。这里没有什么奇怪的
}
接下来,我将接口转换为抽象基(FooBase和BarBase),并对其进行了扩展(FooExt和BarExt):

公共抽象类FooBase
{
公共抽象bool BoolOne{get;set;}
}
公共抽象类
{
公共抽象列表傻瓜{get;protected set;}
}
公共类FooExt:FooBase
{
public override bool BoolOne{get;set;}//实现抽象属性
public bool BoolTwo{get;set;}//添加新属性
}
公共类BarExt:巴巴多斯//错误:未实现愚人
{        
公共重写列表傻瓜列表{get;protected set;}//错误:“类型必须是FooBase”
}
我不明白为什么最后一行出现错误,
“Type必须是FooBase”
。我认为FooExt是多态性的FooBase

我尝试了很多(这里列出的太多)Linq
ConvertAll()
override
new
,并通过构造函数和其他函数传递值的组合,但找不到任何可以编译的东西。我应该使用不同的设计模式吗


这不是的副本,因为我的列表容器是一个接口。这些答案很有帮助,但对这个问题非常正确。

通过覆盖,您无法更改成员签名

想象一下,您的程序的一个用户获得了一个
BarBase
的实例,例如,从服务器或其他什么地方

class MyServer
{
    public BarBase GetBar() { ... }
}

var bar = server.GetBar();
该用户如何知道这个instances
dublist
-属性实际上包含
FooExt
的实例?它不能,因为巴巴多斯提供的合同只说明了清单

如果我们能够做到这一点,我们还可以将
另一个foo
的实例添加到该列表中,该实例也继承自
FooBase

bar.FooList.Add(new AnotherBar())
现在,您的
傻瓜列表将同时包含
FooExt
-和
另一个栏
-实例


因此,在重写时,您必须使用与被重写成员完全相同的签名。

通过重写,您无法更改成员签名

想象一下,您的程序的一个用户获得了一个
BarBase
的实例,例如,从服务器或其他什么地方

class MyServer
{
    public BarBase GetBar() { ... }
}

var bar = server.GetBar();
该用户如何知道这个instances
dublist
-属性实际上包含
FooExt
的实例?它不能,因为巴巴多斯提供的合同只说明了清单

如果我们能够做到这一点,我们还可以将
另一个foo
的实例添加到该列表中,该实例也继承自
FooBase

bar.FooList.Add(new AnotherBar())
现在,您的
傻瓜列表将同时包含
FooExt
-和
另一个栏
-实例


因此,在重写时,您必须使用与被重写成员完全相同的签名。

在被重写的方法中,您更改了类型参数。您不能这样做,因为它使签名不同

您可以使用泛型:

public abstract class Base<T> where T : FooBase
{
    public abstract List<T> FooList { get; protected set; }
}
公共抽象类基,其中T:FooBase
{
公共抽象列表傻瓜{get;protected set;}
}
然后你可以这样覆盖它:

public class Ext : Base<FooExt>
{        
    public override List<FooExt> FooList { get; protected set; }
}
公共类Ext:Base
{        
公共覆盖列表傻瓜{get;protected set;}
}

在重写的方法中,您更改了类型参数。您不能这样做,因为它使签名不同

您可以使用泛型:

public abstract class Base<T> where T : FooBase
{
    public abstract List<T> FooList { get; protected set; }
}
公共抽象类基,其中T:FooBase
{
公共抽象列表傻瓜{get;protected set;}
}
然后你可以这样覆盖它:

public class Ext : Base<FooExt>
{        
    public override List<FooExt> FooList { get; protected set; }
}
公共类Ext:Base
{        
公共覆盖列表傻瓜{get;protected set;}
}

通过重写,您无法更改成员签名。可能会使
IBar
/
BarBase
成为具有泛型类型参数的泛型接口/类,该参数指定了
傻瓜列表的元素类型(将此泛型类型参数约束为从
IFoo
/
FooBase
派生的类型将是一个好主意)通过重写,您无法更改成员签名。可能会使
IBar
/
BarBase
成为具有泛型类型参数的泛型接口/类,该参数指定了
傻瓜列表的元素类型(将此泛型类型参数约束为从
IFoo
/
FooBase
派生的类型将是一个好主意)我解释了为什么,你解释了如何。回答很好。我解释了为什么,你解释了如何。回答很好。