Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

c# Ambiguous methods. Works in dotnetfiddle but not in unity?

Discussion in 'Scripting' started by jasonwt1977, Apr 1, 2015.

  1. jasonwt1977

    jasonwt1977

    Joined:
    Mar 4, 2015
    Posts:
    7
    I hope this post is in the correct location.

    I am having a hard time seeing what I am doing wrong here. I am getting the following error but as far as I can tell everything looks right. The error is directed at the return value in the GenerateSmoothNoise function.

    Assets/ITerrain/Libs/ITNoiseLib/CoherentNoise.cs(48,33): error CS0121: The call is ambiguous between the following methods or properties: `ITNoiseLib.CoherentNoise.GetNoise(byte, int, int, int)' and `ITNoiseLib.CoherentNoise.GetNoise(byte, float, ITMathLib.MathUtils.InterpolationMode)'

    I am pretty new to c# so I am sure I am overlooking something simple but have looked all over the web for a solution but have not found anything yet.

    Any insight would be appreciated.

    Code (csharp):
    1.  
    2. public static float GetNoise(byte seed, int x, int y = 0, int z = 0) {
    3.        ...
    4. }
    5.  
    6. public static float GenerateSmoothNoise(byte seed, int x) {
    7.        // x is an int so I would assume it would call the above GetNoise function.  I have also tried casting it to a int with (int) x, (int) (x-1), ... with the same results.
    8.  
    9.         return (GetNoise(seed, x) / 2.0f + (GetNoise(seed, x - 1) / 4.0f) + (GetNoise(seed, x + 1) / 4.0f)); // Error here
    10. }
    11.  
    12. public static float GetNoise(byte seed, float x, MathUtils.InterpolationMode interpolation_mode = MathUtils.InterpolationMode.LERP) {
    13.       ...
    14. }
    15.  
     
    Last edited: Apr 1, 2015
  2. jasonwt1977

    jasonwt1977

    Joined:
    Mar 4, 2015
    Posts:
    7
    This is really odd. If I cast x to a float in the GenerateSmoothNoise function it does not have any problems. but when I cast it to an int its still ambiguous. I am at a complete loss.
     
  3. jasonwt1977

    jasonwt1977

    Joined:
    Mar 4, 2015
    Posts:
    7
    I have broken this problem down into the simplest form.

    The following fails with the same ambiguous error inside the Bar function.

    Code (csharp):
    1.  
    2. public static float Foo(byte seed, int x) {
    3.     ...
    4. }
    5.      
    6. public static float Bar(byte seed, int x) {
    7.     return (Foo (seed,x));
    8. }
    9.  
    10. public static float Foo(byte seed, float x, short t=1) {
    11.     ...
    12. }
    13.  
    But if I remove the t parameter in the bottom Foo function is has no problems.

    The following works fine

    Code (csharp):
    1.  
    2. public static float Foo(byte seed, int x) {
    3.     ...
    4. }
    5.      
    6. public static float Bar(byte seed, int x) {
    7.     return (Foo (seed,x));
    8. }
    9.  
    10. public static float Foo(byte seed, float x) {
    11.     ...
    12. }
    13.  
     
  4. jasonwt1977

    jasonwt1977

    Joined:
    Mar 4, 2015
    Posts:
    7
  5. Deleted User

    Deleted User

    Guest

    Your error is in GenerateSmoothNoise:
    When you do this: GetNoise(seed, x) it gives you an error.
    Since you have 2 functions called GetNoise each with the same required parameters (only the optional ones are different and you don't pass any) then it doesn't know which GetNoise function it should call.
     
  6. jasonwt1977

    jasonwt1977

    Joined:
    Mar 4, 2015
    Posts:
    7
    Thanks for your reply.

    I thought since I passed an int it would call the version of GetNoise that accepts ints.

    I guess I need to revisit method overloading in C#.
     
  7. jasonwt1977

    jasonwt1977

    Joined:
    Mar 4, 2015
    Posts:
    7
    As it seems you are unable to have default values on overloaded methods.

    I got around this with the following solution.

    Code (csharp):
    1.  
    2. public static float Foo(byte seed, int x) {
    3.     ...
    4. }
    5.    
    6. public static float Bar(byte seed, int x) {
    7.     return (Foo (seed,x));
    8. }
    9.  
    10. public static float Foo(byte seed, float x, short t) {
    11.     ...
    12. }
    13.  
    14. public static float Foo(byte seed, float x) {
    15.     return (Foo(seed, x, 1)); // call the above Foo function with default t value of 1
    16. }
    17.  
    18.  
     
  8. Deleted User

    Deleted User

    Guest

    If you only want to call the one that accepts ints, have you tried casting x as int? Such as GetNoise(seed, (int) x)?
     
  9. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    A better question is. Why would you even want an overloaded method with optional parameters?
     
  10. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    It's possible this is a Unity-specific bug, because Unity doesn't support C# 4, which is when they introduced optional parameters. Instead, Unity implemented its own workaround to allow optional parameters which does some weirdness under the hood to create hidden overloaded functions for each of the versions of the function with and without the optional parameter supplied. So it might be one of those that is actually conflicting. There are a few other bugs with the way Unity handles optional parameters that you should watch out for too if you use them a lot. For example:

    Code (csharp):
    1. int Add(int x, int y = 3) { return x + y; }
    2. Add(5, 0);  //returns 5 in .NET (correct answer) but returns 8 in Unity (wrong answer)
    This is because Unity's workaround with the hidden overload is checking to see if the optional parameter is the default value of its type (0 for an int) and if so, converts it to the optional parameter default (3).
     
    twobob and Kiwasi like this.
  11. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Thanks for the heads up ... that's a doozie :)