If you just specified the correct input type, you can use them:
var voiceInput = new Input() { TypeId = 1, ObjectDefinesInput = new VoiceInput(){ ... } }
and
switch (input.TypeId) { case 1: VoiceInput voiceInput = (VoiceInput)input.ObjectDefinesInput; return new VoiceResponse(voiceInput); default: TextInput textInput = (textInput)input.ObjectDefinesInput; return new TextResponse(textInput ); }
If you need security of a particular type, have your Input class have a general type argument for the input type
public class Input<T> { public int TypeId { get; set; } public T ObjectDefinesInput; }
AND
var voiceInput = new Input<VoiceInput>() { TypeId = 1, ObjectDefinesInput = new VoiceInput(){ ... } }
Then casting is not required:
switch (input.TypeId) { case 1: return new VoiceResponse(input.ObjectDefinesInput); default: return new TextResponse(input.ObjectDefinesInput); }
source share