Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. can this be done without using 'dynamic: build a list of KeyValuePairs, where each item's Type varies ?

can this be done without using 'dynamic: build a list of KeyValuePairs, where each item's Type varies ?

Scheduled Pinned Locked Moved C#
csharpvisual-studiowinformscomquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BillWoodruff
    wrote on last edited by
    #1

    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.TextBox

    So 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

    D M 2 Replies Last reply
    0
    • B BillWoodruff

      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.TextBox

      So 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

      D Offline
      D Offline
      DaveyM69
      wrote on last edited by
      #2

      1. As is often the case, you can replace dynamic with object and it will still work the same. The two are very similar. 2. You passed in the Value not the Key. The GetType method you called returns the true type of the object, not object:

      object o = 1;
      Console.WriteLine(o.GetType()); // System.Int32

      Dave
      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)

      B 1 Reply Last reply
      0
      • B BillWoodruff

        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.TextBox

        So 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

        M Offline
        M Offline
        Martijn Kok
        wrote on last edited by
        #3

        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!"; //OK

        You 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 RuntimeBindingException

        Another 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.5

        value = "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.

        B 1 Reply Last reply
        0
        • D DaveyM69

          1. As is often the case, you can replace dynamic with object and it will still work the same. The two are very similar. 2. You passed in the Value not the Key. The GetType method you called returns the true type of the object, not object:

          object o = 1;
          Console.WriteLine(o.GetType()); // System.Int32

          Dave
          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)

          B Offline
          B Offline
          BillWoodruff
          wrote on last edited by
          #4

          +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

          1 Reply Last reply
          0
          • M Martijn Kok

            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!"; //OK

            You 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 RuntimeBindingException

            Another 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.5

            value = "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.

            B Offline
            B Offline
            BillWoodruff
            wrote on last edited by
            #5

            +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

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups