can this be done without using 'dynamic: build a list of KeyValuePairs, where each item's Type varies ?
-
Note: this "experiment" was actually touched-off by Bob Janova's comment [^] on the recent thread on Tuples, "Tuples in Functions" [^], here, on this forum. I'm not clear exactly why, but, that got me interested in what it would take to build a generic List of KeyValuePairs, where the 'Key would be a 'Type, and the 'Value an instance of that 'Type, and the 'Type for each KeyValuePair would be inferred from the 'Value. The idea was that to to call a function that added items to the List<KeyValuePair> like this, passing in only the actual 'Value for each new KeyValuePair item:
AddToKVPList("tweet");
AddToKVPList(1.567893);
AddToKVPList(new TextBox()); // WinForms dependent ?
I struggled to find a way to do this without using any "higher" .NET facilities, but could not achieve what I wanted: my final solution was
private List<KeyValuePair<Type, dynamic>> _listOkvp = new List<KeyValuePair<Type, dynamic>>();
private void AddToKVPList(object oIn)
{
workingType = oIn.GetType();KeyValuePair newKVP = new KeyValuePair(workingType, oIn); \_listOkvp.Add(newKVP);
}
If we execute the above code, and examine what _listOkvp is after the three calls to AddToKVPList in a 'Command' window in Visual Studio:
> ? _listOkvp
Count = 3
[0]: {[System.String, tweet]}
[1]: {[System.Double, 1.567893]}
[2]: {[System.Windows.Forms.TextBox, System.Windows.Forms.TextBox, Text: ]}Well, yes, that's what I was trying to get to: and, if you add this to iterate and print to the Console everything in the KeyValuePairList:
foreach(var kvp in _listOkvp)
{
Console.WriteLine(kvp.Value.GetType());
}You do get:
System.String
System.Double
System.Windows.Forms.TextBoxSo what's wrong ? :) Two things: 1. I believe I could have achieved this without using 'Dynamic, but I could not find a way to do that. 2. I cannot understand how I did transform the value of the (edit: 'Key)'Value, which was passed in as an 'object' parameter to the method 'AddToKVPList, to an actual instance of the 'Type of the passed in 'Value. Which is wors
-
Note: this "experiment" was actually touched-off by Bob Janova's comment [^] on the recent thread on Tuples, "Tuples in Functions" [^], here, on this forum. I'm not clear exactly why, but, that got me interested in what it would take to build a generic List of KeyValuePairs, where the 'Key would be a 'Type, and the 'Value an instance of that 'Type, and the 'Type for each KeyValuePair would be inferred from the 'Value. The idea was that to to call a function that added items to the List<KeyValuePair> like this, passing in only the actual 'Value for each new KeyValuePair item:
AddToKVPList("tweet");
AddToKVPList(1.567893);
AddToKVPList(new TextBox()); // WinForms dependent ?
I struggled to find a way to do this without using any "higher" .NET facilities, but could not achieve what I wanted: my final solution was
private List<KeyValuePair<Type, dynamic>> _listOkvp = new List<KeyValuePair<Type, dynamic>>();
private void AddToKVPList(object oIn)
{
workingType = oIn.GetType();KeyValuePair newKVP = new KeyValuePair(workingType, oIn); \_listOkvp.Add(newKVP);
}
If we execute the above code, and examine what _listOkvp is after the three calls to AddToKVPList in a 'Command' window in Visual Studio:
> ? _listOkvp
Count = 3
[0]: {[System.String, tweet]}
[1]: {[System.Double, 1.567893]}
[2]: {[System.Windows.Forms.TextBox, System.Windows.Forms.TextBox, Text: ]}Well, yes, that's what I was trying to get to: and, if you add this to iterate and print to the Console everything in the KeyValuePairList:
foreach(var kvp in _listOkvp)
{
Console.WriteLine(kvp.Value.GetType());
}You do get:
System.String
System.Double
System.Windows.Forms.TextBoxSo what's wrong ? :) Two things: 1. I believe I could have achieved this without using 'Dynamic, but I could not find a way to do that. 2. I cannot understand how I did transform the value of the (edit: 'Key)'Value, which was passed in as an 'object' parameter to the method 'AddToKVPList, to an actual instance of the 'Type of the passed in 'Value. Which is wors
1. As is often the case, you can replace
dynamic
withobject
and it will still work the same. The two are very similar. 2. You passed in theValue
not theKey
. TheGetType
method you called returns the true type of the object, notobject
:object o = 1;
Console.WriteLine(o.GetType()); // System.Int32Dave
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) -
Note: this "experiment" was actually touched-off by Bob Janova's comment [^] on the recent thread on Tuples, "Tuples in Functions" [^], here, on this forum. I'm not clear exactly why, but, that got me interested in what it would take to build a generic List of KeyValuePairs, where the 'Key would be a 'Type, and the 'Value an instance of that 'Type, and the 'Type for each KeyValuePair would be inferred from the 'Value. The idea was that to to call a function that added items to the List<KeyValuePair> like this, passing in only the actual 'Value for each new KeyValuePair item:
AddToKVPList("tweet");
AddToKVPList(1.567893);
AddToKVPList(new TextBox()); // WinForms dependent ?
I struggled to find a way to do this without using any "higher" .NET facilities, but could not achieve what I wanted: my final solution was
private List<KeyValuePair<Type, dynamic>> _listOkvp = new List<KeyValuePair<Type, dynamic>>();
private void AddToKVPList(object oIn)
{
workingType = oIn.GetType();KeyValuePair newKVP = new KeyValuePair(workingType, oIn); \_listOkvp.Add(newKVP);
}
If we execute the above code, and examine what _listOkvp is after the three calls to AddToKVPList in a 'Command' window in Visual Studio:
> ? _listOkvp
Count = 3
[0]: {[System.String, tweet]}
[1]: {[System.Double, 1.567893]}
[2]: {[System.Windows.Forms.TextBox, System.Windows.Forms.TextBox, Text: ]}Well, yes, that's what I was trying to get to: and, if you add this to iterate and print to the Console everything in the KeyValuePairList:
foreach(var kvp in _listOkvp)
{
Console.WriteLine(kvp.Value.GetType());
}You do get:
System.String
System.Double
System.Windows.Forms.TextBoxSo what's wrong ? :) Two things: 1. I believe I could have achieved this without using 'Dynamic, but I could not find a way to do that. 2. I cannot understand how I did transform the value of the (edit: 'Key)'Value, which was passed in as an 'object' parameter to the method 'AddToKVPList, to an actual instance of the 'Type of the passed in 'Value. Which is wors
It can be done with a
List<KeyValuePair<Type, object>>
The example doesn't use the advantages of a dynamic (dynamic binding) over an object (static binding). At this article http://msdn.microsoft.com/en-us/magazine/gg598922.aspx[^] the advantages are explained. Objects and dynamics are for a large part the same with one exception that the bindings aren't resolved until runtime. It is as if you tell the compiler "trust me, I know what I'm doing" :cool: If the dymanic contains a System.Windows.Form.Textbox you could do this
dynamic something = new TextBox();
something.Text = "Hello dynamic world!"; //OKYou wouldn't be able to do this with an object. The programmer has to make sure that the something variable does have a Text property. Otherwise you would get a RuntimeBindingException.
dynamic something = "Change the value to a string";
something.Text = "Hello dynamic world!"; //throws RuntimeBindingExceptionAnother advantage of a dynamic would that you could call a method with a specific signature (because the real type of the dynamic is resolved at runtime).
public void DoSomething(string someValue) { Console.WriteLine("The value is a string: {0}", someValue); }
public void DoSomething(double someValue) {
Console.WriteLine("The value is a double: {0}", somevalue); }public void CallTheRightDoSomething()
{
dynamic value = 0.5;
DoSomething(value); // The value is a double: 0.5value = "Now use it as a string";
DoSomehting(value); // The value is a string: Now use it as a string
}With objects this would give an error. Due to the static binding nature of objects you would get a designtime error. var could solve this, but not as flexible as dynamic. I guess using dynamic would only make sense if you really needs the dynamic binding behaviour. If you have functions that have different signatures to handle the values in your list (string, double, textbox), then it would be necessary to use dynamics. Otherwise you could use object.
-
1. As is often the case, you can replace
dynamic
withobject
and it will still work the same. The two are very similar. 2. You passed in theValue
not theKey
. TheGetType
method you called returns the true type of the object, notobject
:object o = 1;
Console.WriteLine(o.GetType()); // System.Int32Dave
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)+5 Thanks, DaveyM69, I edited the OP to correct the mistake you identified: yes, I did pass in the 'Value for the KeyValuePair, not the 'Key ! I regret I did not keep back copies of my various failed attempts, so that I could examine them, now, since you enlightened me that object.GetType() will return the "true" 'Type ! best, Bill
"If you shoot at mimes, should you use a silencer ?" Stephen Wright
-
It can be done with a
List<KeyValuePair<Type, object>>
The example doesn't use the advantages of a dynamic (dynamic binding) over an object (static binding). At this article http://msdn.microsoft.com/en-us/magazine/gg598922.aspx[^] the advantages are explained. Objects and dynamics are for a large part the same with one exception that the bindings aren't resolved until runtime. It is as if you tell the compiler "trust me, I know what I'm doing" :cool: If the dymanic contains a System.Windows.Form.Textbox you could do this
dynamic something = new TextBox();
something.Text = "Hello dynamic world!"; //OKYou wouldn't be able to do this with an object. The programmer has to make sure that the something variable does have a Text property. Otherwise you would get a RuntimeBindingException.
dynamic something = "Change the value to a string";
something.Text = "Hello dynamic world!"; //throws RuntimeBindingExceptionAnother advantage of a dynamic would that you could call a method with a specific signature (because the real type of the dynamic is resolved at runtime).
public void DoSomething(string someValue) { Console.WriteLine("The value is a string: {0}", someValue); }
public void DoSomething(double someValue) {
Console.WriteLine("The value is a double: {0}", somevalue); }public void CallTheRightDoSomething()
{
dynamic value = 0.5;
DoSomething(value); // The value is a double: 0.5value = "Now use it as a string";
DoSomehting(value); // The value is a string: Now use it as a string
}With objects this would give an error. Due to the static binding nature of objects you would get a designtime error. var could solve this, but not as flexible as dynamic. I guess using dynamic would only make sense if you really needs the dynamic binding behaviour. If you have functions that have different signatures to handle the values in your list (string, double, textbox), then it would be necessary to use dynamics. Otherwise you could use object.
+5 All your points about use of 'dynamic are very well articulated; I was aware of the late-binding aspect of dynamic, and have used it, for that purpose, in code (when I had to). In this case, I just finally used 'dynamic because I couldn't get anything else to work :) As I said, in my reponse to DaveyM69, "I regret I did not keep back copies of my various failed attempts, so that I could examine them, now." The OP would have been more valuable, imho, if I had posted my last "failed" attempt, and then the attempt that "worked" for comparison. Thanks for your time ! best, Bill
"If you shoot at mimes, should you use a silencer ?" Stephen Wright