Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.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# 使用yield return返回从基类型继承的对象_C#_Generics_Collections - Fatal编程技术网

C# 使用yield return返回从基类型继承的对象

C# 使用yield return返回从基类型继承的对象,c#,generics,collections,C#,Generics,Collections,我有一个名为Media的bas类,它继承了两个类,Photo和Video。我正在尝试为媒体基类创建一个集合来保存这些照片和视频对象。因此,我创建了一个MediaList类,如下所示: public class MediaList: ICollection<Media> { private readonly XElement _mediaElement; public MediaList(XElement mediaElement) { _me

我有一个名为
Media
的bas类,它继承了两个类,
Photo
Video
。我正在尝试为媒体基类创建一个集合来保存这些照片和视频对象。因此,我创建了一个
MediaList
类,如下所示:

public class MediaList: ICollection<Media>
{
    private readonly XElement _mediaElement;

    public MediaList(XElement mediaElement)
    {
        _mediaElement = mediaElement;            
    }

    public IEnumerator<Media> GetEnumerator()
    {
        foreach (XElement element in _mediaElement.Elements())
        {
            Media media;
            switch (element.Name.LocalName)
            {
                case "video":
                    media = new Video(element);
                    break;
                case "photo":
                    media = new Photo(element);
                    break;
                default:
                    media = null;
                    break;
            }
            yield return media;
        }
    }

    //Rest of ICollection Implementation
}
公共类媒体列表:ICollection
{
私有只读XElement _mediaElement;
公共媒体列表(XElement mediaElement)
{
_mediaElement=mediaElement;
}
公共IEnumerator GetEnumerator()
{
foreach(_mediaElement.Elements()中的XElement元素)
{
媒体;
开关(element.Name.LocalName)
{
案例“视频”:
媒体=新视频(元素);
打破
案例“照片”:
媒体=新照片(元素);
打破
违约:
媒体=空;
打破
}
产量回收介质;
}
}
//ICollection实现的其余部分
}
当我迭代列表时,我得到以下异常:

值“Tool.Photo”不是“Tool.Video”类型,不能在此常规集合中使用


如果我返回一个
媒体
对象,为什么它会抛出异常?有没有更好的方法来解决这个问题?

是否应该将收益率返回的方法键入return
IEnumerable
,而不是
IEnumerator


但更基本的是,这种模式让我有一股难闻的气味。每次在此“集合”上使用foreach时,您都将在
\u mediaElement.Elements()
列表中创建(实例化)每个
照片
视频
对象的新实例。这真的是您想要的吗?

看起来您正试图将
媒体
实例添加到
视频
集合中,但由于其中一个或多个实例是
照片
——您正试图将照片添加到视频集合中,因此失败。错误在您的客户端代码中,而不是在生成的枚举数中。

您的错误在别处。只要视频和照片都是从媒体继承下来的,你写的东西就可以了。也许你试图在其他地方错误地使用它。

试试这个

class Program
{
    static void Main(string[] args)
    {
        var array = new string[] { "video", "photo", "hurf", "photo" };
        var ml = new MediaList(array);
        foreach(var element in ml)
            Console.WriteLine(element.GetType().Name);
        Console.Read();
    }
}

public class Media { }
public class Video : Media { }
public class Photo : Media { }

public class MediaList
{
    private string[] elements;
    public MediaList(string[] elements) { this.elements = elements; }
    public IEnumerator<Media> GetEnumerator()
    {
        foreach (string s in elements)
            switch (s)
            {
                case "video":
                    yield return new Video();
                    break;
                case "photo":
                    yield return new Photo();
                    break;
            }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var数组=新字符串[]{“video”、“photo”、“hurf”、“photo”};
var ml=新媒体列表(数组);
foreach(变量元素,单位为ml)
Console.WriteLine(element.GetType().Name);
Console.Read();
}
}
公共类媒体{}
公开课视频:媒体{}
公开课照片:媒体{}
公共类媒体列表
{
私有字符串[]元素;
公共媒体列表(字符串[]元素){this.elements=elements;}
公共IEnumerator GetEnumerator()
{
foreach(元素中的字符串s)
开关
{
案例“视频”:
返回新视频();
打破
案例“照片”:
返回新照片();
打破
}
}
}
您可以将其插入控制台应用程序进行测试


注意两件不同的事情首先,您永远不会返回空值。这与您的问题没有任何关系,但是没有人希望枚举返回null,这将在以后给您带来问题第二次,我不会投出我所返回的。所有的转换都是隐式的或由编译器处理的,所以我不需要这样做第三个,与原始代码一样编译并工作。您的问题发生在其他地方,如果您将此代码放入控制台应用程序并进行测试,您会发现。

没有媒体不是抽象的。您确定代码完全正确吗?你能展示一下客户代码吗?客户代码中的一个(co/contra)变量。很高兴你找到了你的答案,但看看我的答案。您的代码存在一些样式问题,其中最重要的是从迭代器返回null。您需要显示错误所在的行,以及媒体、照片和视频的定义。yield返回的不是媒体对象吗?(不是媒体对象的枚举器。)枚举器是在调用foreach跟踪集合中的哪个对象是当前对象时创建的状态维护对象,并在foreach每次迭代时将该状态增加到下一个状态。使用yield return时,c#编译器会为您创建一个枚举器。在正常情况下,我同意您的看法,但在这种情况下,媒体对象只是权值,集合只迭代一次。也许我不清楚,但GetEnumerator()方法的返回类型(您作为IEnumerator使用)不清楚仍然需要是收益回报(IEnumerable)所需的回报类型?我的意思是,如果该方法要返回IEnumerator,其中GetEnumerator()中是一个实现正在构造的IEnumerator的对象??您的收益率返回视频或照片对象。视频类和照片类是否实现IEnumerator??我认为不是……在四处挖掘之后,你是对的,我的问题在别处。问题是在哪里?叹气回到逐步通过代码:-)+1这正是我在开始时的代码,直到我走错了方向:-)