none
Why VS2015 to VS2019 finds it as ambiguous when VS2012 & VS2013 understands the difference? RRS feed

  • Question

  • The error message:

    Error CS0121 The call is ambiguous between the following methods or properties: 
    'InjectionHelper.As<TEntity, TModel>(TEntity, params Expression<Func<TEntity, object>>[])' and 
    'InjectionHelper.As<TEntity, TModel>(TEntity, params Map<TEntity, TModel>[])'

    I've an old ASP.NET MVC project based on Framework 4.5. That is getting successfully compiled on VS 2012 & VS 2013 but producing above mentioned error while trying to compile the same on VS 2015 / VS 2017 / VS 2019. 

    Can anybody guide me to understand why this is happening?

    Regards,

    Arup


    Monday, November 4, 2019 10:09 AM

Answers

  • Covariance and contravariance are new features introduced in C# 4.0 / .NET 4.5.

    Before this new feature is introduced there is only one meaning in your statement and the compiler is not confused, but if you compile it with later version(s) you'll be required to specify which one is what you actually looking for.

    • Marked as answer by ArupPaul_2019 Wednesday, December 4, 2019 6:14 AM
    Tuesday, November 12, 2019 9:43 AM
    Answerer

All replies

  • Hi ArupPaul_2019,

    Thank you for posting here.

    According to your description, make sure you don't reference the output binary in your project references.

    Here are some references you can refer to.

    The call is ambiguous between single method i.e extension method

    The call is ambiguous between the following methods: Identical.NameSpace.InitializeComponent() and Identical.NameSpace.InitializeComponent()

    Hope them could be helpful.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 5, 2019 6:01 AM
    Moderator
  • Hi Xingyu Zhao,

    Thank you very much for your response.

    Yes, there were one case of self-referencing issue. I've re-compiled the solution after removing the self-reference  but those errors are still there.

    Actually, if you re-check the error message again then you notice that those are two different extension methods with different parameters, whereas parameter types are same.

    Can you en-light anything further?

    Regards,

    Arup Paul

    Tuesday, November 5, 2019 9:18 AM
  • Hi ArupPaul_2019,

    Thanks for your feedback.

    Could you provide more information or some related code about your two extension methods? It will help us to make a test.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, November 6, 2019 9:04 AM
    Moderator
  • Hi Xingyu Zhao,
    Below are the overloaded extension methods,
    #region As
            /// <summary>
            /// Returns a model AS a specified new model
            /// </summary>
            /// <typeparam name="TModel">Type of return model</typeparam>
            /// <param name="model">Model to map</param>
            /// <returns>Will allways return new model even if the source model is null</returns>
            public static TModel As<TModel>(this object model) where TModel : class, new()
            {
                var returnType = Activator.CreateInstance(typeof(TModel)) as TModel;
                return model != null ? returnType.Inject(model) : returnType;
            }

            /// <summary>
            /// Returns a model AS a specified new model
            /// </summary>
            /// <typeparam name="TEntity">Type of return model</typeparam>
            /// <typeparam name="TModel">Model to map</typeparam>
            /// <param name="model"></param>
            /// <param name="includeObjects">Additional objects to map</param>
            /// <returns></returns>
            public static TModel As<TEntity, TModel>(this TEntity model, params Expression<Func<TEntity, object>>[] includeObjects)
                where TModel : class, new()
                where TEntity : class
            {
                return model.As(includeObjects.Select(Map<TEntity, TModel>.Object).ToArray());
            }

            /// <summary>
            /// Returns a model AS a specified new model
            /// </summary>
            /// <typeparam name="TEntity">Type of return model</typeparam>
            /// <typeparam name="TModel">Model to map</typeparam>
            /// <param name="model"></param>
            /// <param name="mappings">Additional objects and properties to map</param>
            /// <returns></returns>
            public static TModel As<TEntity, TModel>(this TEntity model, params Map<TEntity, TModel>[] mappings)
                where TModel : class, new()
                where TEntity : class
            {
                var returnType = model.As<TModel>();

                if (model == null)
                    return returnType;

                //We start by going through the objects to map
                foreach (var objectMap in mappings.Where(x => x.Type == Map<TEntity, TModel>.MapType.Object))
                    returnType.TrySetPropertyValue(objectMap.Destination, objectMap.MapObject.Invoke(model));

                //Then the properties
                foreach (var propertyMap in mappings.Where(x => x.Type == Map<TEntity, TModel>.MapType.Property))
                    returnType.TrySetPropertyValue(propertyMap.Destination, model.GetPropertyValueAs<object>(propertyMap.From));

                foreach (var propertyMap in mappings.Where(x => x.Type == Map<TEntity, TModel>.MapType.Property))
                    returnType.TrySetPropertyValue(propertyMap.Destination, model.GetPropertyValueAs<object>(propertyMap.From));

                foreach (var propertyMap in mappings.Where(x => x.Type == Map<TEntity, TModel>.MapType.PropertyExpression))
                    returnType.TrySetPropertyValue(propertyMap.Destination, (propertyMap.FromExpression.Compile().Invoke(model)));

                return returnType;
            }
    #endregion 

    these extensions are used as below (serially),
    1> return assessorCompetence.As<AssessorCompetence>();
    2> return retObj.As<User, UserModel>(x => x.MemberGroups.AsListOf<MemberGroup, MemberGroupModel>());
    3> userSignature.As<UserSignatureModel, UserSignature>();

    VS 2012 & 2013 can refer those properly but VS 2015 onward producing the mentioned error for 2 & 3 items.

    Thank you.
    Regards,
    Arup Paul


    Tuesday, November 12, 2019 8:42 AM
  • Covariance and contravariance are new features introduced in C# 4.0 / .NET 4.5.

    Before this new feature is introduced there is only one meaning in your statement and the compiler is not confused, but if you compile it with later version(s) you'll be required to specify which one is what you actually looking for.

    • Marked as answer by ArupPaul_2019 Wednesday, December 4, 2019 6:14 AM
    Tuesday, November 12, 2019 9:43 AM
    Answerer