0

I get the following back from an API

{
  "quiz_submission_events": [
    {
      "id": "3409",
      "event_type": "question_answered",
      "event_data" : {"answer": "42"}
      "created_at": "2014-11-16T13:37:21Z"
    },
    {
      "id": "3410",
      "event_type": "question_flagged",
      "event_data" : { "question_id": "1", "flagged": true }
      "created_at": "2014-11-16T13:37:27Z"
    }
  ]
}

I am trying to create objects to represent this data that can then be used in code.

I currently have something like this

public class PlatformQuizSubmissionEvents
{
    public List<IPlatformQuizSubmissionEvent> QuizSubmissionEvents;
}

public interface IPlatformQuizSubmissionEvent 
{
    public int Id { get; set; }
    public string EventType { get; set; }
    public DateTime CreatedAt { get; set; }
    public IQuestionEventData EventData { get; set; }
}

public class PlatformQuizSubmissionEventBase : IPlatformQuizSubmissionEvent
{
    public int Id { get; set; }
    public string EventType { get; set; }
    public DateTime CreatedAt { get; set; }
    public IQuestionEventData EventData { get; set; }
}

public class QuestionAnsweredEvent : PlatformQuizSubmissionEventBase
{
    public new QuestionAnsweredEventData EventData { get; set; }
}

public interface IQuestionEventData { }

public class QuestionAnsweredEventData : IQuestionEventData
{
    public string QuestionId { get; set; }
    public string Answer { get; set; }
}
    

And then, for example, if I want to return only the "question_answered" events, I have something like this

public List<QuestionAnsweredEvent> GetUserQuizSubmissionQuestionAnswerEvents(
    string courseId, string quizId, int submissionId)
{
    PlatformQuizSubmissionEvents submissionEvents = 
        _ApiRepository.GetUserQuizSubmissionEvents(courseId, quizId, submissionId);

    List<QuestionAnsweredEvent> filtered = submissionEvents.QuizSubmissionEvents
        .Where(qse => qse.EventType == "question_answered")
        .ToList();
}

On this line

I get this error

CS0029: Cannot implicitly convert type 'System.Collections.Generic.List<QuizTime.Core.LTIPlatforms.Shared.IPlatformQuizSubmissionEvent>' to 'System.Collections.Generic.List<QuizTime.Core.LTIPlatforms.Shared.QuestionAnsweredEvent>'

So, I know that what I'm getting back from this code will be data that is a list of QuestionAnsweredEvent objects. However, I'm not sure how to best represent this so that the c# compiler can handle this. I am going to try Automapper, but I'm not sure if that's the right way to go about this: maybe I'm just setting up my interfaces/classes incorrectly?

Rufus L
  • 36,127
  • 5
  • 30
  • 43
Chris Rockwell
  • 1,688
  • 2
  • 21
  • 36
  • Why do you need the result object to be specifically a `List`? Is there any operation that cannot be done with a `IList` instead? In the last case, you could do a direct cast, but that defeats the purpose of coding for interfaces. _Liskov feelings_... – Rodrigo Rodrigues May 26 '21 at 17:25
  • _"I know that what I'm getting back from this code will be data that is a list of QuestionAnsweredEvent objects. However, I'm not sure how to best represent this so that the c# compiler can handle this"_ -- you have to have the right type in the first place. The compiler is correct; the assignment you're trying to make isn't safe. See duplicate for why. The only way to _"represent this so that the C# compiler can handler this"_ is to write the code so that it's actually type-safe, which means either not trying to cast, or returning the right type in the 1st place (i.e. not the interface list) – Peter Duniho May 26 '21 at 17:53

0 Answers0