Store a Action in dictionary












1















What I have is a asynchronous request/response model, when the response is received I want to run an action.



A small code sample of what I'd like to accomplish:



class Program {
static void Main(string args) {
//Make a request and show 'hello world' when the response was received
Connection.Request<MyResponse>("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection.SetResponse("key", new MyResponse("hello world"));
}
}

public class Connection {
static Dictionary<string, Action<BaseResponse>> _dicActions = new Dictionary<string, Action<BaseResponse>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse {
_dicActions.Add(key, action);
}

public static void SetResponse(string key, BaseResponse pResponse) {
_dicActions[key](pResponse);
}
}

public class BaseResponse { }
public class MyResponse : BaseResponse {
public string Value;
public MyResponse(string pValue) {
Value = pValue;
}
}


Of course in the sample above the _dicActions.Add doesn't work.
How could I make the below code work?, for some reason haven't been able to figure it out.










share|improve this question























  • The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set Action<Derived> to instance of Action<Base> baseAction (because that baseAction will always be called with instance of "Derived" which is definitely "Base", but the other way it does not work because not every "Base" is "Derived".

    – Alexei Levenkov
    Jan 3 at 2:47
















1















What I have is a asynchronous request/response model, when the response is received I want to run an action.



A small code sample of what I'd like to accomplish:



class Program {
static void Main(string args) {
//Make a request and show 'hello world' when the response was received
Connection.Request<MyResponse>("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection.SetResponse("key", new MyResponse("hello world"));
}
}

public class Connection {
static Dictionary<string, Action<BaseResponse>> _dicActions = new Dictionary<string, Action<BaseResponse>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse {
_dicActions.Add(key, action);
}

public static void SetResponse(string key, BaseResponse pResponse) {
_dicActions[key](pResponse);
}
}

public class BaseResponse { }
public class MyResponse : BaseResponse {
public string Value;
public MyResponse(string pValue) {
Value = pValue;
}
}


Of course in the sample above the _dicActions.Add doesn't work.
How could I make the below code work?, for some reason haven't been able to figure it out.










share|improve this question























  • The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set Action<Derived> to instance of Action<Base> baseAction (because that baseAction will always be called with instance of "Derived" which is definitely "Base", but the other way it does not work because not every "Base" is "Derived".

    – Alexei Levenkov
    Jan 3 at 2:47














1












1








1








What I have is a asynchronous request/response model, when the response is received I want to run an action.



A small code sample of what I'd like to accomplish:



class Program {
static void Main(string args) {
//Make a request and show 'hello world' when the response was received
Connection.Request<MyResponse>("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection.SetResponse("key", new MyResponse("hello world"));
}
}

public class Connection {
static Dictionary<string, Action<BaseResponse>> _dicActions = new Dictionary<string, Action<BaseResponse>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse {
_dicActions.Add(key, action);
}

public static void SetResponse(string key, BaseResponse pResponse) {
_dicActions[key](pResponse);
}
}

public class BaseResponse { }
public class MyResponse : BaseResponse {
public string Value;
public MyResponse(string pValue) {
Value = pValue;
}
}


Of course in the sample above the _dicActions.Add doesn't work.
How could I make the below code work?, for some reason haven't been able to figure it out.










share|improve this question














What I have is a asynchronous request/response model, when the response is received I want to run an action.



A small code sample of what I'd like to accomplish:



class Program {
static void Main(string args) {
//Make a request and show 'hello world' when the response was received
Connection.Request<MyResponse>("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection.SetResponse("key", new MyResponse("hello world"));
}
}

public class Connection {
static Dictionary<string, Action<BaseResponse>> _dicActions = new Dictionary<string, Action<BaseResponse>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse {
_dicActions.Add(key, action);
}

public static void SetResponse(string key, BaseResponse pResponse) {
_dicActions[key](pResponse);
}
}

public class BaseResponse { }
public class MyResponse : BaseResponse {
public string Value;
public MyResponse(string pValue) {
Value = pValue;
}
}


Of course in the sample above the _dicActions.Add doesn't work.
How could I make the below code work?, for some reason haven't been able to figure it out.







c# generics






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 3 at 2:08









CrazyCrazy

307215




307215













  • The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set Action<Derived> to instance of Action<Base> baseAction (because that baseAction will always be called with instance of "Derived" which is definitely "Base", but the other way it does not work because not every "Base" is "Derived".

    – Alexei Levenkov
    Jan 3 at 2:47



















  • The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set Action<Derived> to instance of Action<Base> baseAction (because that baseAction will always be called with instance of "Derived" which is definitely "Base", but the other way it does not work because not every "Base" is "Derived".

    – Alexei Levenkov
    Jan 3 at 2:47

















The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set Action<Derived> to instance of Action<Base> baseAction (because that baseAction will always be called with instance of "Derived" which is definitely "Base", but the other way it does not work because not every "Base" is "Derived".

– Alexei Levenkov
Jan 3 at 2:47





The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set Action<Derived> to instance of Action<Base> baseAction (because that baseAction will always be called with instance of "Derived" which is definitely "Base", but the other way it does not work because not every "Base" is "Derived".

– Alexei Levenkov
Jan 3 at 2:47












3 Answers
3






active

oldest

votes


















1














To do this properly you really have to ensure that the dictionary is type-safe. This is simple to do. Just change the dictionary from Dictionary<string, Action<BaseResponse>> to Dictionary<string, Dictionary<Type, Delegate>> and then implement Connection like this:



public class Connection
{
static Dictionary<string, Dictionary<Type, Delegate>> _dicActions = new Dictionary<string, Dictionary<Type, Delegate>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse
{
if (!_dicActions.ContainsKey(key))
{
_dicActions.Add(key, new Dictionary<Type, Delegate>());
}
_dicActions[key].Add(typeof(T), action);
}

public static void SetResponse<T>(string key, T pResponse) where T : BaseResponse
{
((Action<T>)_dicActions[key][typeof(T)])(pResponse);
}
}


That works with your existing code like a treat and it ensures that you don't mismatch your key and your T when calling SetResponse.






share|improve this answer


























  • Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

    – Alexei Levenkov
    Jan 3 at 5:31











  • @AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

    – Enigmativity
    Jan 3 at 5:49



















1














Why don't you use Action<BaseResponse> directly?



public static void Request<T>(string key, Action<BaseResponse> action) where T : BaseResponse


Or you can make the class generic:



public static void Main()
{
//Make a request and show 'hello world' when the response was received
Connection<MyResponse>.Request("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection<MyResponse>.SetResponse("key", new MyResponse("hello world"));
}

public class Connection<T> where T: BaseResponse
{
static Dictionary<string, Action<T>> _dicActions = new Dictionary<string, Action<T>>();
public static void Request(string key, Action<T> action)
{
_dicActions.Add(key, action);
}

public static void SetResponse(string key, T pResponse)
{
_dicActions[key](pResponse);
}
}





share|improve this answer


























  • Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

    – Michael Randall
    Jan 3 at 2:20











  • Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

    – Crazy
    Jan 3 at 2:21













  • @Crazy I've edited my answer.

    – ojlovecd
    Jan 3 at 2:25











  • @Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

    – Brian Ogden
    Jan 3 at 2:34






  • 1





    @Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

    – Alexei Levenkov
    Jan 3 at 2:51



















-1














If you just want to make a smaller change in your code, you can convert the action like this:



_dicActions.Add(key, o => action((T)o));





share|improve this answer
























  • Sure... Also moving compile time errors to become run-time errors is rarely good idea.

    – Alexei Levenkov
    Jan 3 at 2:48











  • It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

    – Crazy
    Jan 3 at 2:52











  • @Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

    – Alexei Levenkov
    Jan 3 at 3:02













  • This is such a bad idea - it's is throwing away type-safety.

    – Enigmativity
    Jan 3 at 4:15











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54015485%2fstore-a-actiont-in-dictionary%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














To do this properly you really have to ensure that the dictionary is type-safe. This is simple to do. Just change the dictionary from Dictionary<string, Action<BaseResponse>> to Dictionary<string, Dictionary<Type, Delegate>> and then implement Connection like this:



public class Connection
{
static Dictionary<string, Dictionary<Type, Delegate>> _dicActions = new Dictionary<string, Dictionary<Type, Delegate>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse
{
if (!_dicActions.ContainsKey(key))
{
_dicActions.Add(key, new Dictionary<Type, Delegate>());
}
_dicActions[key].Add(typeof(T), action);
}

public static void SetResponse<T>(string key, T pResponse) where T : BaseResponse
{
((Action<T>)_dicActions[key][typeof(T)])(pResponse);
}
}


That works with your existing code like a treat and it ensures that you don't mismatch your key and your T when calling SetResponse.






share|improve this answer


























  • Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

    – Alexei Levenkov
    Jan 3 at 5:31











  • @AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

    – Enigmativity
    Jan 3 at 5:49
















1














To do this properly you really have to ensure that the dictionary is type-safe. This is simple to do. Just change the dictionary from Dictionary<string, Action<BaseResponse>> to Dictionary<string, Dictionary<Type, Delegate>> and then implement Connection like this:



public class Connection
{
static Dictionary<string, Dictionary<Type, Delegate>> _dicActions = new Dictionary<string, Dictionary<Type, Delegate>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse
{
if (!_dicActions.ContainsKey(key))
{
_dicActions.Add(key, new Dictionary<Type, Delegate>());
}
_dicActions[key].Add(typeof(T), action);
}

public static void SetResponse<T>(string key, T pResponse) where T : BaseResponse
{
((Action<T>)_dicActions[key][typeof(T)])(pResponse);
}
}


That works with your existing code like a treat and it ensures that you don't mismatch your key and your T when calling SetResponse.






share|improve this answer


























  • Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

    – Alexei Levenkov
    Jan 3 at 5:31











  • @AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

    – Enigmativity
    Jan 3 at 5:49














1












1








1







To do this properly you really have to ensure that the dictionary is type-safe. This is simple to do. Just change the dictionary from Dictionary<string, Action<BaseResponse>> to Dictionary<string, Dictionary<Type, Delegate>> and then implement Connection like this:



public class Connection
{
static Dictionary<string, Dictionary<Type, Delegate>> _dicActions = new Dictionary<string, Dictionary<Type, Delegate>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse
{
if (!_dicActions.ContainsKey(key))
{
_dicActions.Add(key, new Dictionary<Type, Delegate>());
}
_dicActions[key].Add(typeof(T), action);
}

public static void SetResponse<T>(string key, T pResponse) where T : BaseResponse
{
((Action<T>)_dicActions[key][typeof(T)])(pResponse);
}
}


That works with your existing code like a treat and it ensures that you don't mismatch your key and your T when calling SetResponse.






share|improve this answer















To do this properly you really have to ensure that the dictionary is type-safe. This is simple to do. Just change the dictionary from Dictionary<string, Action<BaseResponse>> to Dictionary<string, Dictionary<Type, Delegate>> and then implement Connection like this:



public class Connection
{
static Dictionary<string, Dictionary<Type, Delegate>> _dicActions = new Dictionary<string, Dictionary<Type, Delegate>>();
public static void Request<T>(string key, Action<T> action) where T : BaseResponse
{
if (!_dicActions.ContainsKey(key))
{
_dicActions.Add(key, new Dictionary<Type, Delegate>());
}
_dicActions[key].Add(typeof(T), action);
}

public static void SetResponse<T>(string key, T pResponse) where T : BaseResponse
{
((Action<T>)_dicActions[key][typeof(T)])(pResponse);
}
}


That works with your existing code like a treat and it ensures that you don't mismatch your key and your T when calling SetResponse.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 22:33

























answered Jan 3 at 4:21









EnigmativityEnigmativity

77.9k966135




77.9k966135













  • Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

    – Alexei Levenkov
    Jan 3 at 5:31











  • @AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

    – Enigmativity
    Jan 3 at 5:49



















  • Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

    – Alexei Levenkov
    Jan 3 at 5:31











  • @AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

    – Enigmativity
    Jan 3 at 5:49

















Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

– Alexei Levenkov
Jan 3 at 5:31





Nice. In production code consider it you want to add some null check in SetResponse, also there is a good chance that NRE is actually correct in this case as I'd expect set of handlers should match set of responses and missing handler is actually bug rather than expected behavior.

– Alexei Levenkov
Jan 3 at 5:31













@AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

– Enigmativity
Jan 3 at 5:49





@AlexeiLevenkov - Yes, I would generally put in null check code in here. It's just a bit simplified for easier understanding.

– Enigmativity
Jan 3 at 5:49













1














Why don't you use Action<BaseResponse> directly?



public static void Request<T>(string key, Action<BaseResponse> action) where T : BaseResponse


Or you can make the class generic:



public static void Main()
{
//Make a request and show 'hello world' when the response was received
Connection<MyResponse>.Request("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection<MyResponse>.SetResponse("key", new MyResponse("hello world"));
}

public class Connection<T> where T: BaseResponse
{
static Dictionary<string, Action<T>> _dicActions = new Dictionary<string, Action<T>>();
public static void Request(string key, Action<T> action)
{
_dicActions.Add(key, action);
}

public static void SetResponse(string key, T pResponse)
{
_dicActions[key](pResponse);
}
}





share|improve this answer


























  • Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

    – Michael Randall
    Jan 3 at 2:20











  • Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

    – Crazy
    Jan 3 at 2:21













  • @Crazy I've edited my answer.

    – ojlovecd
    Jan 3 at 2:25











  • @Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

    – Brian Ogden
    Jan 3 at 2:34






  • 1





    @Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

    – Alexei Levenkov
    Jan 3 at 2:51
















1














Why don't you use Action<BaseResponse> directly?



public static void Request<T>(string key, Action<BaseResponse> action) where T : BaseResponse


Or you can make the class generic:



public static void Main()
{
//Make a request and show 'hello world' when the response was received
Connection<MyResponse>.Request("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection<MyResponse>.SetResponse("key", new MyResponse("hello world"));
}

public class Connection<T> where T: BaseResponse
{
static Dictionary<string, Action<T>> _dicActions = new Dictionary<string, Action<T>>();
public static void Request(string key, Action<T> action)
{
_dicActions.Add(key, action);
}

public static void SetResponse(string key, T pResponse)
{
_dicActions[key](pResponse);
}
}





share|improve this answer


























  • Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

    – Michael Randall
    Jan 3 at 2:20











  • Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

    – Crazy
    Jan 3 at 2:21













  • @Crazy I've edited my answer.

    – ojlovecd
    Jan 3 at 2:25











  • @Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

    – Brian Ogden
    Jan 3 at 2:34






  • 1





    @Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

    – Alexei Levenkov
    Jan 3 at 2:51














1












1








1







Why don't you use Action<BaseResponse> directly?



public static void Request<T>(string key, Action<BaseResponse> action) where T : BaseResponse


Or you can make the class generic:



public static void Main()
{
//Make a request and show 'hello world' when the response was received
Connection<MyResponse>.Request("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection<MyResponse>.SetResponse("key", new MyResponse("hello world"));
}

public class Connection<T> where T: BaseResponse
{
static Dictionary<string, Action<T>> _dicActions = new Dictionary<string, Action<T>>();
public static void Request(string key, Action<T> action)
{
_dicActions.Add(key, action);
}

public static void SetResponse(string key, T pResponse)
{
_dicActions[key](pResponse);
}
}





share|improve this answer















Why don't you use Action<BaseResponse> directly?



public static void Request<T>(string key, Action<BaseResponse> action) where T : BaseResponse


Or you can make the class generic:



public static void Main()
{
//Make a request and show 'hello world' when the response was received
Connection<MyResponse>.Request("key", (MyResponse) => {
Console.WriteLine(MyResponse.Value);
});

//set the response making the action write "hello world"
Connection<MyResponse>.SetResponse("key", new MyResponse("hello world"));
}

public class Connection<T> where T: BaseResponse
{
static Dictionary<string, Action<T>> _dicActions = new Dictionary<string, Action<T>>();
public static void Request(string key, Action<T> action)
{
_dicActions.Add(key, action);
}

public static void SetResponse(string key, T pResponse)
{
_dicActions[key](pResponse);
}
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 2:24

























answered Jan 3 at 2:15









ojlovecdojlovecd

3,83111218




3,83111218













  • Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

    – Michael Randall
    Jan 3 at 2:20











  • Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

    – Crazy
    Jan 3 at 2:21













  • @Crazy I've edited my answer.

    – ojlovecd
    Jan 3 at 2:25











  • @Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

    – Brian Ogden
    Jan 3 at 2:34






  • 1





    @Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

    – Alexei Levenkov
    Jan 3 at 2:51



















  • Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

    – Michael Randall
    Jan 3 at 2:20











  • Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

    – Crazy
    Jan 3 at 2:21













  • @Crazy I've edited my answer.

    – ojlovecd
    Jan 3 at 2:25











  • @Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

    – Brian Ogden
    Jan 3 at 2:34






  • 1





    @Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

    – Alexei Levenkov
    Jan 3 at 2:51

















Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

– Michael Randall
Jan 3 at 2:20





Its also worth noting, the generic parameter is redundant now and also the OP will have to cast Console.WriteLine(((MyResponse)MyResponse).Value);

– Michael Randall
Jan 3 at 2:20













Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

– Crazy
Jan 3 at 2:21







Because when doing that I'd have to cast the parameter in the action to MyResponse, I'd like to avoid casting as this prevents developer mistakes and is cleaner.

– Crazy
Jan 3 at 2:21















@Crazy I've edited my answer.

– ojlovecd
Jan 3 at 2:25





@Crazy I've edited my answer.

– ojlovecd
Jan 3 at 2:25













@Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

– Brian Ogden
Jan 3 at 2:34





@Crazy seems like making the Connection class generic solves the problem as ojlovecd suggests

– Brian Ogden
Jan 3 at 2:34




1




1





@Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

– Alexei Levenkov
Jan 3 at 2:51





@Crazy creating a lot of sibling types with generics may not be what you want... (like you no longer can have collection of "Connection" instances) as long as it works for you and you understand what is actually going on then all good.

– Alexei Levenkov
Jan 3 at 2:51











-1














If you just want to make a smaller change in your code, you can convert the action like this:



_dicActions.Add(key, o => action((T)o));





share|improve this answer
























  • Sure... Also moving compile time errors to become run-time errors is rarely good idea.

    – Alexei Levenkov
    Jan 3 at 2:48











  • It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

    – Crazy
    Jan 3 at 2:52











  • @Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

    – Alexei Levenkov
    Jan 3 at 3:02













  • This is such a bad idea - it's is throwing away type-safety.

    – Enigmativity
    Jan 3 at 4:15
















-1














If you just want to make a smaller change in your code, you can convert the action like this:



_dicActions.Add(key, o => action((T)o));





share|improve this answer
























  • Sure... Also moving compile time errors to become run-time errors is rarely good idea.

    – Alexei Levenkov
    Jan 3 at 2:48











  • It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

    – Crazy
    Jan 3 at 2:52











  • @Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

    – Alexei Levenkov
    Jan 3 at 3:02













  • This is such a bad idea - it's is throwing away type-safety.

    – Enigmativity
    Jan 3 at 4:15














-1












-1








-1







If you just want to make a smaller change in your code, you can convert the action like this:



_dicActions.Add(key, o => action((T)o));





share|improve this answer













If you just want to make a smaller change in your code, you can convert the action like this:



_dicActions.Add(key, o => action((T)o));






share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 3 at 2:46









XiaosuXiaosu

3701620




3701620













  • Sure... Also moving compile time errors to become run-time errors is rarely good idea.

    – Alexei Levenkov
    Jan 3 at 2:48











  • It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

    – Crazy
    Jan 3 at 2:52











  • @Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

    – Alexei Levenkov
    Jan 3 at 3:02













  • This is such a bad idea - it's is throwing away type-safety.

    – Enigmativity
    Jan 3 at 4:15



















  • Sure... Also moving compile time errors to become run-time errors is rarely good idea.

    – Alexei Levenkov
    Jan 3 at 2:48











  • It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

    – Crazy
    Jan 3 at 2:52











  • @Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

    – Alexei Levenkov
    Jan 3 at 3:02













  • This is such a bad idea - it's is throwing away type-safety.

    – Enigmativity
    Jan 3 at 4:15

















Sure... Also moving compile time errors to become run-time errors is rarely good idea.

– Alexei Levenkov
Jan 3 at 2:48





Sure... Also moving compile time errors to become run-time errors is rarely good idea.

– Alexei Levenkov
Jan 3 at 2:48













It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

– Crazy
Jan 3 at 2:52





It does work with minimal changes, also requires less refactoring on my end. Why would i be getting run-time errors?, casting to T can't really make anything go wrong right?

– Crazy
Jan 3 at 2:52













@Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

– Alexei Levenkov
Jan 3 at 3:02







@Crazy I've added explanation on the question already. Read it carefully. It is not possible to say if it applies to your particular case but for code shown so far it can easily fail at run-time: you try to call Action<MyResponse> with instance of MyOtherResponse : BaseResponse

– Alexei Levenkov
Jan 3 at 3:02















This is such a bad idea - it's is throwing away type-safety.

– Enigmativity
Jan 3 at 4:15





This is such a bad idea - it's is throwing away type-safety.

– Enigmativity
Jan 3 at 4:15


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54015485%2fstore-a-actiont-in-dictionary%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Angular Downloading a file using contenturl with Basic Authentication

Olmecas

Can't read property showImagePicker of undefined in react native iOS