What is the return type for a generic list returning an anonymous 2-string type?











up vote
0
down vote

favorite












I have this function:



public static List<string> JoinDataTablesMultipleColumns(DataTable dt1, DataTable dt2, string col1, string col2, string col3) {
var multiJoin = from table1 in dt1.AsEnumerable()
join table2 in dt2.AsEnumerable()
on new {
Col1 = table1.Field < string > (col1),
Col2 = table1.Field < string > (col2),
Col3 = table1.Field < string > (col3),
}
equals new {
Col1 = table2.Field < string > (col1),
Col2 = table2.Field < string > (col2),
Col3 = table2.Field < string > (col3),
}
select new {
SeriesID = table1.Field < string > ("SeriesID"),
CatID = table2.Field < string > ("CatID")
};

//if ( multiJoin != null )
// return multiJoin.ToList();
//else
return null;
}


It works perfectly except that I have the wrong return type. The only way I can compile and run it is by returning null. When I stop the debugger before returning and examine multiJoin.ToList() in the watch window, it's exactly what I want:



enter image description here



But the return type is wrong. I keep trying List<string, string>, but that won't compile. Probably a simple thing but I am stuck. Any ideas?










share|improve this question


























    up vote
    0
    down vote

    favorite












    I have this function:



    public static List<string> JoinDataTablesMultipleColumns(DataTable dt1, DataTable dt2, string col1, string col2, string col3) {
    var multiJoin = from table1 in dt1.AsEnumerable()
    join table2 in dt2.AsEnumerable()
    on new {
    Col1 = table1.Field < string > (col1),
    Col2 = table1.Field < string > (col2),
    Col3 = table1.Field < string > (col3),
    }
    equals new {
    Col1 = table2.Field < string > (col1),
    Col2 = table2.Field < string > (col2),
    Col3 = table2.Field < string > (col3),
    }
    select new {
    SeriesID = table1.Field < string > ("SeriesID"),
    CatID = table2.Field < string > ("CatID")
    };

    //if ( multiJoin != null )
    // return multiJoin.ToList();
    //else
    return null;
    }


    It works perfectly except that I have the wrong return type. The only way I can compile and run it is by returning null. When I stop the debugger before returning and examine multiJoin.ToList() in the watch window, it's exactly what I want:



    enter image description here



    But the return type is wrong. I keep trying List<string, string>, but that won't compile. Probably a simple thing but I am stuck. Any ideas?










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have this function:



      public static List<string> JoinDataTablesMultipleColumns(DataTable dt1, DataTable dt2, string col1, string col2, string col3) {
      var multiJoin = from table1 in dt1.AsEnumerable()
      join table2 in dt2.AsEnumerable()
      on new {
      Col1 = table1.Field < string > (col1),
      Col2 = table1.Field < string > (col2),
      Col3 = table1.Field < string > (col3),
      }
      equals new {
      Col1 = table2.Field < string > (col1),
      Col2 = table2.Field < string > (col2),
      Col3 = table2.Field < string > (col3),
      }
      select new {
      SeriesID = table1.Field < string > ("SeriesID"),
      CatID = table2.Field < string > ("CatID")
      };

      //if ( multiJoin != null )
      // return multiJoin.ToList();
      //else
      return null;
      }


      It works perfectly except that I have the wrong return type. The only way I can compile and run it is by returning null. When I stop the debugger before returning and examine multiJoin.ToList() in the watch window, it's exactly what I want:



      enter image description here



      But the return type is wrong. I keep trying List<string, string>, but that won't compile. Probably a simple thing but I am stuck. Any ideas?










      share|improve this question













      I have this function:



      public static List<string> JoinDataTablesMultipleColumns(DataTable dt1, DataTable dt2, string col1, string col2, string col3) {
      var multiJoin = from table1 in dt1.AsEnumerable()
      join table2 in dt2.AsEnumerable()
      on new {
      Col1 = table1.Field < string > (col1),
      Col2 = table1.Field < string > (col2),
      Col3 = table1.Field < string > (col3),
      }
      equals new {
      Col1 = table2.Field < string > (col1),
      Col2 = table2.Field < string > (col2),
      Col3 = table2.Field < string > (col3),
      }
      select new {
      SeriesID = table1.Field < string > ("SeriesID"),
      CatID = table2.Field < string > ("CatID")
      };

      //if ( multiJoin != null )
      // return multiJoin.ToList();
      //else
      return null;
      }


      It works perfectly except that I have the wrong return type. The only way I can compile and run it is by returning null. When I stop the debugger before returning and examine multiJoin.ToList() in the watch window, it's exactly what I want:



      enter image description here



      But the return type is wrong. I keep trying List<string, string>, but that won't compile. Probably a simple thing but I am stuck. Any ideas?







      c# anonymous-types






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 8 at 0:23









      HerrimanCoder

      1,443144480




      1,443144480
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          Instead of attempting returning an anonymous type (you can't declare an anonymous return type for your method), create a named type to hold your data:



          public class Item
          {
          public string SeriesID { get; set;}
          //...
          }


          and use it instead of the anonymous type that you are currently selecting at the end of your query.



          ...select new Item {
          SeriesID = table1.Field < string > ("SeriesID"),
          CatID = table2.Field < string > ("CatID")
          };





          share|improve this answer





















          • In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
            – HerrimanCoder
            Nov 8 at 0:53










          • This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
            – Brian
            Nov 9 at 14:02




















          up vote
          12
          down vote













          As you note, you're getting a list of anonymous type. Anonymous types are not designed to cross out of the methods that create them. There are ways to make that work, but they are confusing, difficult and arcane.



          Do not attempt to do this with anonymous types. In C# 7, you can use a tuple type and return List<(string, string)>, and then do



          select (table1.Field<string>("SeriesID"), table2.Field<string>("CatID"))


          In other versions of C#, make a nominal pair type and create an instance of it in your select clause.






          share|improve this answer























          • When you say make a nominal pair type, is that the same as what spender is suggesting?
            – HerrimanCoder
            Nov 8 at 0:34










          • @HerrimanCoder: Yes, exactly that.
            – Eric Lippert
            Nov 8 at 0:35










          • I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
            – HerrimanCoder
            Nov 8 at 0:36






          • 3




            Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
            – spender
            Nov 8 at 0:37






          • 2




            @spender: Apparently this is the day of me typing things at the same time as other people.
            – Eric Lippert
            Nov 8 at 0:38











          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',
          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%2f53199894%2fwhat-is-the-return-type-for-a-generic-list-returning-an-anonymous-2-string-type%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          5
          down vote



          accepted










          Instead of attempting returning an anonymous type (you can't declare an anonymous return type for your method), create a named type to hold your data:



          public class Item
          {
          public string SeriesID { get; set;}
          //...
          }


          and use it instead of the anonymous type that you are currently selecting at the end of your query.



          ...select new Item {
          SeriesID = table1.Field < string > ("SeriesID"),
          CatID = table2.Field < string > ("CatID")
          };





          share|improve this answer





















          • In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
            – HerrimanCoder
            Nov 8 at 0:53










          • This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
            – Brian
            Nov 9 at 14:02

















          up vote
          5
          down vote



          accepted










          Instead of attempting returning an anonymous type (you can't declare an anonymous return type for your method), create a named type to hold your data:



          public class Item
          {
          public string SeriesID { get; set;}
          //...
          }


          and use it instead of the anonymous type that you are currently selecting at the end of your query.



          ...select new Item {
          SeriesID = table1.Field < string > ("SeriesID"),
          CatID = table2.Field < string > ("CatID")
          };





          share|improve this answer





















          • In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
            – HerrimanCoder
            Nov 8 at 0:53










          • This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
            – Brian
            Nov 9 at 14:02















          up vote
          5
          down vote



          accepted







          up vote
          5
          down vote



          accepted






          Instead of attempting returning an anonymous type (you can't declare an anonymous return type for your method), create a named type to hold your data:



          public class Item
          {
          public string SeriesID { get; set;}
          //...
          }


          and use it instead of the anonymous type that you are currently selecting at the end of your query.



          ...select new Item {
          SeriesID = table1.Field < string > ("SeriesID"),
          CatID = table2.Field < string > ("CatID")
          };





          share|improve this answer












          Instead of attempting returning an anonymous type (you can't declare an anonymous return type for your method), create a named type to hold your data:



          public class Item
          {
          public string SeriesID { get; set;}
          //...
          }


          and use it instead of the anonymous type that you are currently selecting at the end of your query.



          ...select new Item {
          SeriesID = table1.Field < string > ("SeriesID"),
          CatID = table2.Field < string > ("CatID")
          };






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 8 at 0:31









          spender

          85.8k21157276




          85.8k21157276












          • In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
            – HerrimanCoder
            Nov 8 at 0:53










          • This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
            – Brian
            Nov 9 at 14:02




















          • In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
            – HerrimanCoder
            Nov 8 at 0:53










          • This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
            – Brian
            Nov 9 at 14:02


















          In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
          – HerrimanCoder
          Nov 8 at 0:53




          In the end, this approach may be a little more old-school than Eric's, but it doesn't cause me to lose named properties as the tuple does.
          – HerrimanCoder
          Nov 8 at 0:53












          This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
          – Brian
          Nov 9 at 14:02






          This would be so much cleaner if we had Record Types. They're specifically designed to solve this sort of problem. Alas, it keeps getting pushed back. There are a surprising number of low-level implementation details that have made it difficult to come up with a spec for this.
          – Brian
          Nov 9 at 14:02














          up vote
          12
          down vote













          As you note, you're getting a list of anonymous type. Anonymous types are not designed to cross out of the methods that create them. There are ways to make that work, but they are confusing, difficult and arcane.



          Do not attempt to do this with anonymous types. In C# 7, you can use a tuple type and return List<(string, string)>, and then do



          select (table1.Field<string>("SeriesID"), table2.Field<string>("CatID"))


          In other versions of C#, make a nominal pair type and create an instance of it in your select clause.






          share|improve this answer























          • When you say make a nominal pair type, is that the same as what spender is suggesting?
            – HerrimanCoder
            Nov 8 at 0:34










          • @HerrimanCoder: Yes, exactly that.
            – Eric Lippert
            Nov 8 at 0:35










          • I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
            – HerrimanCoder
            Nov 8 at 0:36






          • 3




            Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
            – spender
            Nov 8 at 0:37






          • 2




            @spender: Apparently this is the day of me typing things at the same time as other people.
            – Eric Lippert
            Nov 8 at 0:38















          up vote
          12
          down vote













          As you note, you're getting a list of anonymous type. Anonymous types are not designed to cross out of the methods that create them. There are ways to make that work, but they are confusing, difficult and arcane.



          Do not attempt to do this with anonymous types. In C# 7, you can use a tuple type and return List<(string, string)>, and then do



          select (table1.Field<string>("SeriesID"), table2.Field<string>("CatID"))


          In other versions of C#, make a nominal pair type and create an instance of it in your select clause.






          share|improve this answer























          • When you say make a nominal pair type, is that the same as what spender is suggesting?
            – HerrimanCoder
            Nov 8 at 0:34










          • @HerrimanCoder: Yes, exactly that.
            – Eric Lippert
            Nov 8 at 0:35










          • I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
            – HerrimanCoder
            Nov 8 at 0:36






          • 3




            Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
            – spender
            Nov 8 at 0:37






          • 2




            @spender: Apparently this is the day of me typing things at the same time as other people.
            – Eric Lippert
            Nov 8 at 0:38













          up vote
          12
          down vote










          up vote
          12
          down vote









          As you note, you're getting a list of anonymous type. Anonymous types are not designed to cross out of the methods that create them. There are ways to make that work, but they are confusing, difficult and arcane.



          Do not attempt to do this with anonymous types. In C# 7, you can use a tuple type and return List<(string, string)>, and then do



          select (table1.Field<string>("SeriesID"), table2.Field<string>("CatID"))


          In other versions of C#, make a nominal pair type and create an instance of it in your select clause.






          share|improve this answer














          As you note, you're getting a list of anonymous type. Anonymous types are not designed to cross out of the methods that create them. There are ways to make that work, but they are confusing, difficult and arcane.



          Do not attempt to do this with anonymous types. In C# 7, you can use a tuple type and return List<(string, string)>, and then do



          select (table1.Field<string>("SeriesID"), table2.Field<string>("CatID"))


          In other versions of C#, make a nominal pair type and create an instance of it in your select clause.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 8 at 0:36

























          answered Nov 8 at 0:31









          Eric Lippert

          530k14510421923




          530k14510421923












          • When you say make a nominal pair type, is that the same as what spender is suggesting?
            – HerrimanCoder
            Nov 8 at 0:34










          • @HerrimanCoder: Yes, exactly that.
            – Eric Lippert
            Nov 8 at 0:35










          • I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
            – HerrimanCoder
            Nov 8 at 0:36






          • 3




            Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
            – spender
            Nov 8 at 0:37






          • 2




            @spender: Apparently this is the day of me typing things at the same time as other people.
            – Eric Lippert
            Nov 8 at 0:38


















          • When you say make a nominal pair type, is that the same as what spender is suggesting?
            – HerrimanCoder
            Nov 8 at 0:34










          • @HerrimanCoder: Yes, exactly that.
            – Eric Lippert
            Nov 8 at 0:35










          • I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
            – HerrimanCoder
            Nov 8 at 0:36






          • 3




            Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
            – spender
            Nov 8 at 0:37






          • 2




            @spender: Apparently this is the day of me typing things at the same time as other people.
            – Eric Lippert
            Nov 8 at 0:38
















          When you say make a nominal pair type, is that the same as what spender is suggesting?
          – HerrimanCoder
          Nov 8 at 0:34




          When you say make a nominal pair type, is that the same as what spender is suggesting?
          – HerrimanCoder
          Nov 8 at 0:34












          @HerrimanCoder: Yes, exactly that.
          – Eric Lippert
          Nov 8 at 0:35




          @HerrimanCoder: Yes, exactly that.
          – Eric Lippert
          Nov 8 at 0:35












          I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
          – HerrimanCoder
          Nov 8 at 0:36




          I must be in c# 7 because the compiler doesn't complain about List<(string, string)>, but then it complains about what I'm returning: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string SeriesID, string CatID>>' to 'System.Collections.Generic.List<(string, string)>'
          – HerrimanCoder
          Nov 8 at 0:36




          3




          3




          Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
          – spender
          Nov 8 at 0:37




          Going the tuple route, I'd probably go for a List<(string SeriesID,string CatID)> making the data returned in the tuple easy to work with at the other end of the method call.
          – spender
          Nov 8 at 0:37




          2




          2




          @spender: Apparently this is the day of me typing things at the same time as other people.
          – Eric Lippert
          Nov 8 at 0:38




          @spender: Apparently this is the day of me typing things at the same time as other people.
          – Eric Lippert
          Nov 8 at 0:38


















          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.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • 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%2f53199894%2fwhat-is-the-return-type-for-a-generic-list-returning-an-anonymous-2-string-type%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







          這個網誌中的熱門文章

          Tangent Lines Diagram Along Smooth Curve

          Yusuf al-Mu'taman ibn Hud

          Zucchini