Ambiguous / conflicting constructors in a generic class

I have a generic class:

public class BaseFieldValue<T>
{
    public BaseFieldValue()
    {
        //...
    }

    public BaseFieldValue(string value)
    {
        //...
    }

    public BaseFieldValue(T value)
    {
        //...
    }
}

      

Fine. With the exception of...

var myValue = new BaseFieldValue<string>("hello");

      

Unfortunately. An unwanted constructor is being called. There are several ways to solve the problem. What's the best solution?

+2


source to share


5 answers


I would probably do one of the overloads in the factory method:



public static BaseFieldValue<T> Parse(string value){}

      

+7


source


You can do the following:

public class BaseFieldValue<T>
{
    public struct Special
    {
        internal string m_value;
        public Special(string value)
        {
            m_value = value;
        }
    }

    public BaseFieldValue()
    {
        //...
    }

    public BaseFieldValue(Special value)
    {
        //...
    }

    public BaseFieldValue(T value)
    {
        //...
    }
}

      



... or you can add an additional ignored boolean parameter to your custom constructor to simply eliminate it.

+2


source


Can't make Type Contraints do what I wanted, so my workaround removes the ambiguous constructor while keeping a special case for the string:

public class BaseFieldValue<T>
{
    public BaseFieldValue()
    {
        //...
    } 

    public BaseFieldValue(T value) 
    {
        //however many things you need to test for here
        if (typeof(T) == typeof(string))
        {
            SpecialBaseFieldValue(value.ToString());
        }
        else
        {
            //everything else
        }
        //...
    }

    private void SpecialBaseFieldValue(string value)
    {
        //...
    }

}

      

+1


source


Disgusting hack, but probably no worse than any of the alternatives:

public class BaseFieldValue<T>
{
    public BaseFieldValue()
    {
        // ...
    }

    public BaseFieldValue(StringWrapper value)
    {
        // ...
    }

    public BaseFieldValue(T value)
    {
        // ...
    }

    public class StringWrapper
    {
        private string _value;

        public static implicit operator string(StringWrapper sw)
        {
            return sw._value;
        }

        public static implicit operator StringWrapper(string s)
        {
            return new StringWrapper { _value = s };
        }
    }
}

      

And now it can be used as needed:

// call the generic constructor
var myValue = new BaseFieldValue<string>("hello");

// call the string constructor
var myValue = new BaseFieldValue<int>("hello");

      

0


source


Maybe you can try thi:

var myValue = new BaseFieldValue<Object>("hello" as Object);  

      

0


source







All Articles