Misunderstanding of .NET on overloaded methods with different parameters (Call Ambiguous)












15















I have a problem with some overloaded methods and I will try to give a simple implementation of it.



So here is a class contains two methods below:



public class MyRepo<TEntity>
{
public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
{
//Do something
}

public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
{
//Do something
}
}


and this my entity:



public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
}


Here is where I'm utilizing it:



{
...
MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
myRepo.GetData(x => x.Id == 1); // The ambiguity point
...
}


The problem is that I just have two methods with same name and different arguments so, based on OOP polymorphism concepts, I expect .NET to understand my desired method.



But it's obvious .NET cannot understand it because the instance form of Expression<Func<TEntity, Boolean>> and Func<TEntity, Boolean> are the same and this the compile-time error which .NET raises:



The call is ambiguous between the following methods or properties:
'Program.MyRepo<TEntity>.GetData(Expression<Func<TEntity, bool>>)' and
'Program.MyRepo<TEntity>.GetData(Func<TEntity, bool>)'


The question is: how can I prevent this compile-time error?



My preference is to do not touch the way I'm calling GetData() at this line:



myRepo.GetData(x => x.Id == 1);









share|improve this question





























    15















    I have a problem with some overloaded methods and I will try to give a simple implementation of it.



    So here is a class contains two methods below:



    public class MyRepo<TEntity>
    {
    public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
    {
    //Do something
    }

    public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
    {
    //Do something
    }
    }


    and this my entity:



    public class MyEntity
    {
    public int Id { get; set; }
    public string Name { get; set; }
    }


    Here is where I'm utilizing it:



    {
    ...
    MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
    myRepo.GetData(x => x.Id == 1); // The ambiguity point
    ...
    }


    The problem is that I just have two methods with same name and different arguments so, based on OOP polymorphism concepts, I expect .NET to understand my desired method.



    But it's obvious .NET cannot understand it because the instance form of Expression<Func<TEntity, Boolean>> and Func<TEntity, Boolean> are the same and this the compile-time error which .NET raises:



    The call is ambiguous between the following methods or properties:
    'Program.MyRepo<TEntity>.GetData(Expression<Func<TEntity, bool>>)' and
    'Program.MyRepo<TEntity>.GetData(Func<TEntity, bool>)'


    The question is: how can I prevent this compile-time error?



    My preference is to do not touch the way I'm calling GetData() at this line:



    myRepo.GetData(x => x.Id == 1);









    share|improve this question



























      15












      15








      15


      1






      I have a problem with some overloaded methods and I will try to give a simple implementation of it.



      So here is a class contains two methods below:



      public class MyRepo<TEntity>
      {
      public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
      {
      //Do something
      }

      public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
      {
      //Do something
      }
      }


      and this my entity:



      public class MyEntity
      {
      public int Id { get; set; }
      public string Name { get; set; }
      }


      Here is where I'm utilizing it:



      {
      ...
      MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
      myRepo.GetData(x => x.Id == 1); // The ambiguity point
      ...
      }


      The problem is that I just have two methods with same name and different arguments so, based on OOP polymorphism concepts, I expect .NET to understand my desired method.



      But it's obvious .NET cannot understand it because the instance form of Expression<Func<TEntity, Boolean>> and Func<TEntity, Boolean> are the same and this the compile-time error which .NET raises:



      The call is ambiguous between the following methods or properties:
      'Program.MyRepo<TEntity>.GetData(Expression<Func<TEntity, bool>>)' and
      'Program.MyRepo<TEntity>.GetData(Func<TEntity, bool>)'


      The question is: how can I prevent this compile-time error?



      My preference is to do not touch the way I'm calling GetData() at this line:



      myRepo.GetData(x => x.Id == 1);









      share|improve this question
















      I have a problem with some overloaded methods and I will try to give a simple implementation of it.



      So here is a class contains two methods below:



      public class MyRepo<TEntity>
      {
      public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
      {
      //Do something
      }

      public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
      {
      //Do something
      }
      }


      and this my entity:



      public class MyEntity
      {
      public int Id { get; set; }
      public string Name { get; set; }
      }


      Here is where I'm utilizing it:



      {
      ...
      MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
      myRepo.GetData(x => x.Id == 1); // The ambiguity point
      ...
      }


      The problem is that I just have two methods with same name and different arguments so, based on OOP polymorphism concepts, I expect .NET to understand my desired method.



      But it's obvious .NET cannot understand it because the instance form of Expression<Func<TEntity, Boolean>> and Func<TEntity, Boolean> are the same and this the compile-time error which .NET raises:



      The call is ambiguous between the following methods or properties:
      'Program.MyRepo<TEntity>.GetData(Expression<Func<TEntity, bool>>)' and
      'Program.MyRepo<TEntity>.GetData(Func<TEntity, bool>)'


      The question is: how can I prevent this compile-time error?



      My preference is to do not touch the way I'm calling GetData() at this line:



      myRepo.GetData(x => x.Id == 1);






      c# polymorphism






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 2 at 4:40









      paxdiablo

      639k17212551677




      639k17212551677










      asked Jan 2 at 4:36









      Mohammad NikraveshMohammad Nikravesh

      4961521




      4961521
























          5 Answers
          5






          active

          oldest

          votes


















          12














          Lambda expressions (x=> x.Id==1) do not have type by themselves - they automatically "cast" to Expression or Func/delegate of matching type when type is known. I.e. Why must a lambda expression be cast when supplied as a plain Delegate parameter deals with similar issue just between different delegate types.



          In your case methods that are potential candidate suggest both variants and compiler can't make a choice.



          If you really have to keep same name then callers will have to specify type themselves:



           myRepo.GetData((Expression<Func<TEntity, Boolean>>)(x => x.Id == 1));
          myRepo.GetData((Func<TEntity, Boolean>)(x => x.Id == 2));


          I don't think you can use extension method for one of alternatives as search will stop at the class level. So really having methods with different names is the only real option (if you need both). Consider if just Expression version is enough. Alternatively you can split them between different classes (similar how extensions of IQueryable take Expression when similar methods on IEnumerable take Func (see QueryableExtenasions).






          share|improve this answer
























          • I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

            – Mohammad Nikravesh
            Jan 2 at 8:17



















          8





          +50









          I believe the simplest way you can get rid of overloading confusion is to cast your input prior to sending it to the function. This can be done implicitly(inline) or in the form of defining a typed input(recommended way) rather than an anonymous one. Here is how i tested this and it works without giving off that warning.



          MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
          Func<MyEntity, bool> predicate = x => x.Id == 1;
          Expression<Func<MyEntity, bool>> expression = x => x.Id == 1;
          // both below lines are fine now
          myRepo.GetData(predicate);
          myRepo.GetData(expression);


          Apparently C# compiler is not precise enough to differentiate between the two because it demands some heuristic behavior, and anonymous inputs are inherently same. Anyhow, this workaround can solve the issue.






          share|improve this answer


























          • @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

            – Svek
            Jan 11 at 4:44





















          4














          The problem is that when you compile the expression you will create a method with that same signature that the second.



          I recommend you change the name of the first method



          Also If you are going to use Expression return an IQueryable to take advantage of the deferred execution.






          share|improve this answer































            4














            I changed your class and solved the problem:



            public class MyRepo<TEntity>
            {
            public void GetData(Expression<Func<TEntity, bool>> expression, out List<TEntity> result)
            {
            result = null;
            }

            public List<TEntity> GetData(Func<TEntity, bool> whereClause)
            {
            return null;
            }
            }

            private void button1_Click(object sender, EventArgs e)
            {
            var myRepo = new MyRepo<MyEntity>();
            var i = myRepo.GetData(x => x.Id == 1);
            myRepo.GetData(x => x.Id == 1, out i);
            }





            share|improve this answer
























            • Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

              – Mohammad Nikravesh
              Jan 2 at 8:08











            • Although this does solve this specific incident, it does not solve the ambiguity problem in general.

              – Tohnmeister
              Jan 8 at 12:56



















            4














            Consider using Interface inheritance for those two methods. According to SOLID principles you should avoid using references of a concrete type, and instead you should use abstractions via Interfaces. Something like this:



            public interface IQueryDataByPredicateExpression 
            {
            List<TEntity> GetData(Expression<Func<TEntity, Boolean>> whereClause);
            }

            public interface IQueryDataByPredicate
            {
            List<TEntity> GetData(Func<TEntity,Boolean> whereClause);

            }

            public class MyRepo<TEntity> : IQueryDataByPredicateExpression, IQueryDataByPredicate
            {
            public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
            {
            //Do something
            }

            public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
            {
            //Do something
            }
            }


            Now depending the way you want to do your queries, you should use the variable of the interface type that you desire. Now you should have one reference per interface referencing the same instance of Repo.



            IQueryDataByPredicateExpression  queryRepoWithPredicateExpression = myRepo as IQueryDataByPredicateExpression;

            IQueryDataByPredicate queryRepoWithPredicate = myRepo as IQueryDataByPredicate;


            queryRepoWithPredicateExpression.GetData(x => x.Id == 1);
            queryRepoWithPredicate.GetData(x => x.Id == 2);


            But if you cannot, or want change the way you are calling those methods then Alexei Levenkov answer looks great






            share|improve this answer























              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%2f54001248%2fmisunderstanding-of-net-on-overloaded-methods-with-different-parameters-call-a%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              12














              Lambda expressions (x=> x.Id==1) do not have type by themselves - they automatically "cast" to Expression or Func/delegate of matching type when type is known. I.e. Why must a lambda expression be cast when supplied as a plain Delegate parameter deals with similar issue just between different delegate types.



              In your case methods that are potential candidate suggest both variants and compiler can't make a choice.



              If you really have to keep same name then callers will have to specify type themselves:



               myRepo.GetData((Expression<Func<TEntity, Boolean>>)(x => x.Id == 1));
              myRepo.GetData((Func<TEntity, Boolean>)(x => x.Id == 2));


              I don't think you can use extension method for one of alternatives as search will stop at the class level. So really having methods with different names is the only real option (if you need both). Consider if just Expression version is enough. Alternatively you can split them between different classes (similar how extensions of IQueryable take Expression when similar methods on IEnumerable take Func (see QueryableExtenasions).






              share|improve this answer
























              • I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

                – Mohammad Nikravesh
                Jan 2 at 8:17
















              12














              Lambda expressions (x=> x.Id==1) do not have type by themselves - they automatically "cast" to Expression or Func/delegate of matching type when type is known. I.e. Why must a lambda expression be cast when supplied as a plain Delegate parameter deals with similar issue just between different delegate types.



              In your case methods that are potential candidate suggest both variants and compiler can't make a choice.



              If you really have to keep same name then callers will have to specify type themselves:



               myRepo.GetData((Expression<Func<TEntity, Boolean>>)(x => x.Id == 1));
              myRepo.GetData((Func<TEntity, Boolean>)(x => x.Id == 2));


              I don't think you can use extension method for one of alternatives as search will stop at the class level. So really having methods with different names is the only real option (if you need both). Consider if just Expression version is enough. Alternatively you can split them between different classes (similar how extensions of IQueryable take Expression when similar methods on IEnumerable take Func (see QueryableExtenasions).






              share|improve this answer
























              • I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

                – Mohammad Nikravesh
                Jan 2 at 8:17














              12












              12








              12







              Lambda expressions (x=> x.Id==1) do not have type by themselves - they automatically "cast" to Expression or Func/delegate of matching type when type is known. I.e. Why must a lambda expression be cast when supplied as a plain Delegate parameter deals with similar issue just between different delegate types.



              In your case methods that are potential candidate suggest both variants and compiler can't make a choice.



              If you really have to keep same name then callers will have to specify type themselves:



               myRepo.GetData((Expression<Func<TEntity, Boolean>>)(x => x.Id == 1));
              myRepo.GetData((Func<TEntity, Boolean>)(x => x.Id == 2));


              I don't think you can use extension method for one of alternatives as search will stop at the class level. So really having methods with different names is the only real option (if you need both). Consider if just Expression version is enough. Alternatively you can split them between different classes (similar how extensions of IQueryable take Expression when similar methods on IEnumerable take Func (see QueryableExtenasions).






              share|improve this answer













              Lambda expressions (x=> x.Id==1) do not have type by themselves - they automatically "cast" to Expression or Func/delegate of matching type when type is known. I.e. Why must a lambda expression be cast when supplied as a plain Delegate parameter deals with similar issue just between different delegate types.



              In your case methods that are potential candidate suggest both variants and compiler can't make a choice.



              If you really have to keep same name then callers will have to specify type themselves:



               myRepo.GetData((Expression<Func<TEntity, Boolean>>)(x => x.Id == 1));
              myRepo.GetData((Func<TEntity, Boolean>)(x => x.Id == 2));


              I don't think you can use extension method for one of alternatives as search will stop at the class level. So really having methods with different names is the only real option (if you need both). Consider if just Expression version is enough. Alternatively you can split them between different classes (similar how extensions of IQueryable take Expression when similar methods on IEnumerable take Func (see QueryableExtenasions).







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jan 2 at 7:26









              Alexei LevenkovAlexei Levenkov

              85.2k892138




              85.2k892138













              • I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

                – Mohammad Nikravesh
                Jan 2 at 8:17



















              • I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

                – Mohammad Nikravesh
                Jan 2 at 8:17

















              I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

              – Mohammad Nikravesh
              Jan 2 at 8:17





              I appreciate your answer and seems will solve the compile-time issue, But the point is I have to change the places which I'm calling GetData() as I said my preference is to avoid that, BTW, your idea seems great and practical.

              – Mohammad Nikravesh
              Jan 2 at 8:17













              8





              +50









              I believe the simplest way you can get rid of overloading confusion is to cast your input prior to sending it to the function. This can be done implicitly(inline) or in the form of defining a typed input(recommended way) rather than an anonymous one. Here is how i tested this and it works without giving off that warning.



              MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
              Func<MyEntity, bool> predicate = x => x.Id == 1;
              Expression<Func<MyEntity, bool>> expression = x => x.Id == 1;
              // both below lines are fine now
              myRepo.GetData(predicate);
              myRepo.GetData(expression);


              Apparently C# compiler is not precise enough to differentiate between the two because it demands some heuristic behavior, and anonymous inputs are inherently same. Anyhow, this workaround can solve the issue.






              share|improve this answer


























              • @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

                – Svek
                Jan 11 at 4:44


















              8





              +50









              I believe the simplest way you can get rid of overloading confusion is to cast your input prior to sending it to the function. This can be done implicitly(inline) or in the form of defining a typed input(recommended way) rather than an anonymous one. Here is how i tested this and it works without giving off that warning.



              MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
              Func<MyEntity, bool> predicate = x => x.Id == 1;
              Expression<Func<MyEntity, bool>> expression = x => x.Id == 1;
              // both below lines are fine now
              myRepo.GetData(predicate);
              myRepo.GetData(expression);


              Apparently C# compiler is not precise enough to differentiate between the two because it demands some heuristic behavior, and anonymous inputs are inherently same. Anyhow, this workaround can solve the issue.






              share|improve this answer


























              • @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

                – Svek
                Jan 11 at 4:44
















              8





              +50







              8





              +50



              8




              +50





              I believe the simplest way you can get rid of overloading confusion is to cast your input prior to sending it to the function. This can be done implicitly(inline) or in the form of defining a typed input(recommended way) rather than an anonymous one. Here is how i tested this and it works without giving off that warning.



              MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
              Func<MyEntity, bool> predicate = x => x.Id == 1;
              Expression<Func<MyEntity, bool>> expression = x => x.Id == 1;
              // both below lines are fine now
              myRepo.GetData(predicate);
              myRepo.GetData(expression);


              Apparently C# compiler is not precise enough to differentiate between the two because it demands some heuristic behavior, and anonymous inputs are inherently same. Anyhow, this workaround can solve the issue.






              share|improve this answer















              I believe the simplest way you can get rid of overloading confusion is to cast your input prior to sending it to the function. This can be done implicitly(inline) or in the form of defining a typed input(recommended way) rather than an anonymous one. Here is how i tested this and it works without giving off that warning.



              MyRepo<MyEntity> myRepo = new MyRepo<MyEntity>();
              Func<MyEntity, bool> predicate = x => x.Id == 1;
              Expression<Func<MyEntity, bool>> expression = x => x.Id == 1;
              // both below lines are fine now
              myRepo.GetData(predicate);
              myRepo.GetData(expression);


              Apparently C# compiler is not precise enough to differentiate between the two because it demands some heuristic behavior, and anonymous inputs are inherently same. Anyhow, this workaround can solve the issue.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 9 at 4:15

























              answered Jan 9 at 3:59









              Siavash RostamiSiavash Rostami

              8331719




              8331719













              • @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

                – Svek
                Jan 11 at 4:44





















              • @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

                – Svek
                Jan 11 at 4:44



















              @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

              – Svek
              Jan 11 at 4:44







              @MohammadNikravesh Just curious, but how is this answer different from @AlexeiLevenkov's answer? You had stated in the comments that his answer was not what you wanted, but this one is? What is the difference between these two answers, do they not both perform explicit casting?

              – Svek
              Jan 11 at 4:44













              4














              The problem is that when you compile the expression you will create a method with that same signature that the second.



              I recommend you change the name of the first method



              Also If you are going to use Expression return an IQueryable to take advantage of the deferred execution.






              share|improve this answer




























                4














                The problem is that when you compile the expression you will create a method with that same signature that the second.



                I recommend you change the name of the first method



                Also If you are going to use Expression return an IQueryable to take advantage of the deferred execution.






                share|improve this answer


























                  4












                  4








                  4







                  The problem is that when you compile the expression you will create a method with that same signature that the second.



                  I recommend you change the name of the first method



                  Also If you are going to use Expression return an IQueryable to take advantage of the deferred execution.






                  share|improve this answer













                  The problem is that when you compile the expression you will create a method with that same signature that the second.



                  I recommend you change the name of the first method



                  Also If you are going to use Expression return an IQueryable to take advantage of the deferred execution.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 2 at 5:24









                  Fredy Adriano Jimenez MartinezFredy Adriano Jimenez Martinez

                  30416




                  30416























                      4














                      I changed your class and solved the problem:



                      public class MyRepo<TEntity>
                      {
                      public void GetData(Expression<Func<TEntity, bool>> expression, out List<TEntity> result)
                      {
                      result = null;
                      }

                      public List<TEntity> GetData(Func<TEntity, bool> whereClause)
                      {
                      return null;
                      }
                      }

                      private void button1_Click(object sender, EventArgs e)
                      {
                      var myRepo = new MyRepo<MyEntity>();
                      var i = myRepo.GetData(x => x.Id == 1);
                      myRepo.GetData(x => x.Id == 1, out i);
                      }





                      share|improve this answer
























                      • Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

                        – Mohammad Nikravesh
                        Jan 2 at 8:08











                      • Although this does solve this specific incident, it does not solve the ambiguity problem in general.

                        – Tohnmeister
                        Jan 8 at 12:56
















                      4














                      I changed your class and solved the problem:



                      public class MyRepo<TEntity>
                      {
                      public void GetData(Expression<Func<TEntity, bool>> expression, out List<TEntity> result)
                      {
                      result = null;
                      }

                      public List<TEntity> GetData(Func<TEntity, bool> whereClause)
                      {
                      return null;
                      }
                      }

                      private void button1_Click(object sender, EventArgs e)
                      {
                      var myRepo = new MyRepo<MyEntity>();
                      var i = myRepo.GetData(x => x.Id == 1);
                      myRepo.GetData(x => x.Id == 1, out i);
                      }





                      share|improve this answer
























                      • Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

                        – Mohammad Nikravesh
                        Jan 2 at 8:08











                      • Although this does solve this specific incident, it does not solve the ambiguity problem in general.

                        – Tohnmeister
                        Jan 8 at 12:56














                      4












                      4








                      4







                      I changed your class and solved the problem:



                      public class MyRepo<TEntity>
                      {
                      public void GetData(Expression<Func<TEntity, bool>> expression, out List<TEntity> result)
                      {
                      result = null;
                      }

                      public List<TEntity> GetData(Func<TEntity, bool> whereClause)
                      {
                      return null;
                      }
                      }

                      private void button1_Click(object sender, EventArgs e)
                      {
                      var myRepo = new MyRepo<MyEntity>();
                      var i = myRepo.GetData(x => x.Id == 1);
                      myRepo.GetData(x => x.Id == 1, out i);
                      }





                      share|improve this answer













                      I changed your class and solved the problem:



                      public class MyRepo<TEntity>
                      {
                      public void GetData(Expression<Func<TEntity, bool>> expression, out List<TEntity> result)
                      {
                      result = null;
                      }

                      public List<TEntity> GetData(Func<TEntity, bool> whereClause)
                      {
                      return null;
                      }
                      }

                      private void button1_Click(object sender, EventArgs e)
                      {
                      var myRepo = new MyRepo<MyEntity>();
                      var i = myRepo.GetData(x => x.Id == 1);
                      myRepo.GetData(x => x.Id == 1, out i);
                      }






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jan 2 at 7:29









                      CodeManCodeMan

                      557311




                      557311













                      • Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

                        – Mohammad Nikravesh
                        Jan 2 at 8:08











                      • Although this does solve this specific incident, it does not solve the ambiguity problem in general.

                        – Tohnmeister
                        Jan 8 at 12:56



















                      • Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

                        – Mohammad Nikravesh
                        Jan 2 at 8:08











                      • Although this does solve this specific incident, it does not solve the ambiguity problem in general.

                        – Tohnmeister
                        Jan 8 at 12:56

















                      Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

                      – Mohammad Nikravesh
                      Jan 2 at 8:08





                      Also, this is another approach to change the signature of methods. and it will solve my problem, But the point is I have to go deep through the codes in all the places which I'm calling GetData and change them all, I'm looking for a solution to avoid that. BTW, Thank you for your helpful answer

                      – Mohammad Nikravesh
                      Jan 2 at 8:08













                      Although this does solve this specific incident, it does not solve the ambiguity problem in general.

                      – Tohnmeister
                      Jan 8 at 12:56





                      Although this does solve this specific incident, it does not solve the ambiguity problem in general.

                      – Tohnmeister
                      Jan 8 at 12:56











                      4














                      Consider using Interface inheritance for those two methods. According to SOLID principles you should avoid using references of a concrete type, and instead you should use abstractions via Interfaces. Something like this:



                      public interface IQueryDataByPredicateExpression 
                      {
                      List<TEntity> GetData(Expression<Func<TEntity, Boolean>> whereClause);
                      }

                      public interface IQueryDataByPredicate
                      {
                      List<TEntity> GetData(Func<TEntity,Boolean> whereClause);

                      }

                      public class MyRepo<TEntity> : IQueryDataByPredicateExpression, IQueryDataByPredicate
                      {
                      public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
                      {
                      //Do something
                      }

                      public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
                      {
                      //Do something
                      }
                      }


                      Now depending the way you want to do your queries, you should use the variable of the interface type that you desire. Now you should have one reference per interface referencing the same instance of Repo.



                      IQueryDataByPredicateExpression  queryRepoWithPredicateExpression = myRepo as IQueryDataByPredicateExpression;

                      IQueryDataByPredicate queryRepoWithPredicate = myRepo as IQueryDataByPredicate;


                      queryRepoWithPredicateExpression.GetData(x => x.Id == 1);
                      queryRepoWithPredicate.GetData(x => x.Id == 2);


                      But if you cannot, or want change the way you are calling those methods then Alexei Levenkov answer looks great






                      share|improve this answer




























                        4














                        Consider using Interface inheritance for those two methods. According to SOLID principles you should avoid using references of a concrete type, and instead you should use abstractions via Interfaces. Something like this:



                        public interface IQueryDataByPredicateExpression 
                        {
                        List<TEntity> GetData(Expression<Func<TEntity, Boolean>> whereClause);
                        }

                        public interface IQueryDataByPredicate
                        {
                        List<TEntity> GetData(Func<TEntity,Boolean> whereClause);

                        }

                        public class MyRepo<TEntity> : IQueryDataByPredicateExpression, IQueryDataByPredicate
                        {
                        public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
                        {
                        //Do something
                        }

                        public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
                        {
                        //Do something
                        }
                        }


                        Now depending the way you want to do your queries, you should use the variable of the interface type that you desire. Now you should have one reference per interface referencing the same instance of Repo.



                        IQueryDataByPredicateExpression  queryRepoWithPredicateExpression = myRepo as IQueryDataByPredicateExpression;

                        IQueryDataByPredicate queryRepoWithPredicate = myRepo as IQueryDataByPredicate;


                        queryRepoWithPredicateExpression.GetData(x => x.Id == 1);
                        queryRepoWithPredicate.GetData(x => x.Id == 2);


                        But if you cannot, or want change the way you are calling those methods then Alexei Levenkov answer looks great






                        share|improve this answer


























                          4












                          4








                          4







                          Consider using Interface inheritance for those two methods. According to SOLID principles you should avoid using references of a concrete type, and instead you should use abstractions via Interfaces. Something like this:



                          public interface IQueryDataByPredicateExpression 
                          {
                          List<TEntity> GetData(Expression<Func<TEntity, Boolean>> whereClause);
                          }

                          public interface IQueryDataByPredicate
                          {
                          List<TEntity> GetData(Func<TEntity,Boolean> whereClause);

                          }

                          public class MyRepo<TEntity> : IQueryDataByPredicateExpression, IQueryDataByPredicate
                          {
                          public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
                          {
                          //Do something
                          }

                          public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
                          {
                          //Do something
                          }
                          }


                          Now depending the way you want to do your queries, you should use the variable of the interface type that you desire. Now you should have one reference per interface referencing the same instance of Repo.



                          IQueryDataByPredicateExpression  queryRepoWithPredicateExpression = myRepo as IQueryDataByPredicateExpression;

                          IQueryDataByPredicate queryRepoWithPredicate = myRepo as IQueryDataByPredicate;


                          queryRepoWithPredicateExpression.GetData(x => x.Id == 1);
                          queryRepoWithPredicate.GetData(x => x.Id == 2);


                          But if you cannot, or want change the way you are calling those methods then Alexei Levenkov answer looks great






                          share|improve this answer













                          Consider using Interface inheritance for those two methods. According to SOLID principles you should avoid using references of a concrete type, and instead you should use abstractions via Interfaces. Something like this:



                          public interface IQueryDataByPredicateExpression 
                          {
                          List<TEntity> GetData(Expression<Func<TEntity, Boolean>> whereClause);
                          }

                          public interface IQueryDataByPredicate
                          {
                          List<TEntity> GetData(Func<TEntity,Boolean> whereClause);

                          }

                          public class MyRepo<TEntity> : IQueryDataByPredicateExpression, IQueryDataByPredicate
                          {
                          public List<TEntity> GetData(Expression<Func<TEntity, Boolean>> expression)
                          {
                          //Do something
                          }

                          public List<TEntity> GetData(Func<TEntity,Boolean> whereClause)
                          {
                          //Do something
                          }
                          }


                          Now depending the way you want to do your queries, you should use the variable of the interface type that you desire. Now you should have one reference per interface referencing the same instance of Repo.



                          IQueryDataByPredicateExpression  queryRepoWithPredicateExpression = myRepo as IQueryDataByPredicateExpression;

                          IQueryDataByPredicate queryRepoWithPredicate = myRepo as IQueryDataByPredicate;


                          queryRepoWithPredicateExpression.GetData(x => x.Id == 1);
                          queryRepoWithPredicate.GetData(x => x.Id == 2);


                          But if you cannot, or want change the way you are calling those methods then Alexei Levenkov answer looks great







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jan 10 at 18:31









                          Vitor PaulinoVitor Paulino

                          1034




                          1034






























                              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%2f54001248%2fmisunderstanding-of-net-on-overloaded-methods-with-different-parameters-call-a%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

                              Monofisismo

                              Angular Downloading a file using contenturl with Basic Authentication

                              Olmecas