泛型类中的模糊/冲突构造函数

时间:2009-10-09 01:48:24

标签: c# generics

我有一个通用类:

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

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

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

精细。除了...

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

糟糕。调用不需要的构造函数。有很多方法可以解决这个问题。什么是最好的解决方案?

5 个答案:

答案 0 :(得分:7)

我可能会将其中一个重载变为工厂方法:

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

答案 1 :(得分:2)

您可以执行以下操作:

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)
    {
        //...
    }
}

...或者,您可以在特殊构造函数中添加一个额外忽略的布尔参数,只是为了消除歧义。

答案 2 :(得分:1)

无法使Type Contraints做我想要的,所以我的解决方法是删除不明确的构造函数,同时保留字符串的特殊情况:

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)
    {
        //...
    }

}

答案 3 :(得分:0)

讨厌的黑客攻击,但可能并不比任何替代方案更糟糕:

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 };
        }
    }
}

现在它可以根据需要使用:

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

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

答案 4 :(得分:0)

可能你可以试试这个:

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