Store a Action in dictionary
![Multi tool use Multi tool use](http://sgv.ssvwv.com/sg/ssvwvcomimagb.png)
Multi tool use
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
add a comment |
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
The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can setAction<Derived>
to instance ofAction<Base> baseAction
(because thatbaseAction
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
add a comment |
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
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
c# generics
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 setAction<Derived>
to instance ofAction<Base> baseAction
(because thatbaseAction
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
add a comment |
The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can setAction<Derived>
to instance ofAction<Base> baseAction
(because thatbaseAction
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
add a comment |
3 Answers
3
active
oldest
votes
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
.
Nice. In production code consider it you want to add some null check inSetResponse
, 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
add a comment |
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);
}
}
Its also worth noting, the generic parameter is redundant now and also the OP will have to castConsole.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
|
show 2 more comments
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));
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 callAction<MyResponse>
with instance ofMyOtherResponse : 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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
.
Nice. In production code consider it you want to add some null check inSetResponse
, 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
add a comment |
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
.
Nice. In production code consider it you want to add some null check inSetResponse
, 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
add a comment |
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
.
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
.
edited Jan 3 at 22:33
answered Jan 3 at 4:21
![](https://i.stack.imgur.com/0iE2z.jpg?s=32&g=1)
![](https://i.stack.imgur.com/0iE2z.jpg?s=32&g=1)
EnigmativityEnigmativity
77.9k966135
77.9k966135
Nice. In production code consider it you want to add some null check inSetResponse
, 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
add a comment |
Nice. In production code consider it you want to add some null check inSetResponse
, 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
add a comment |
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);
}
}
Its also worth noting, the generic parameter is redundant now and also the OP will have to castConsole.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
|
show 2 more comments
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);
}
}
Its also worth noting, the generic parameter is redundant now and also the OP will have to castConsole.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
|
show 2 more comments
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);
}
}
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);
}
}
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 castConsole.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
|
show 2 more comments
Its also worth noting, the generic parameter is redundant now and also the OP will have to castConsole.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
|
show 2 more comments
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));
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 callAction<MyResponse>
with instance ofMyOtherResponse : 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
add a comment |
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));
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 callAction<MyResponse>
with instance ofMyOtherResponse : 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
add a comment |
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));
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));
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 callAction<MyResponse>
with instance ofMyOtherResponse : 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
add a comment |
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 callAction<MyResponse>
with instance ofMyOtherResponse : 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
P V7aSASnJsEGHvyxfa 4PxwgRWdJmp
The explanation for CS1661 error you see is blogs.msdn.microsoft.com/csharpfaq/2010/02/16/… - you can set
Action<Derived>
to instance ofAction<Base> baseAction
(because thatbaseAction
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