繁体   English   中英

C#自定义类型声明-不起作用

[英]C# Custom Type Declaration - Not Working

天儿真好,

对于帖子的长度,我们深表歉意,但是代码是必需的。

我想在C#中创建自己的值类型。 我已经实现了一个TCountryID结构,但是在编写以下代码后,由于存在以下问题,我仍然缺少一些东西:

    int iTest = 0;
    TCountryID tcidTest;
    iTest = tcidTest;

1)无法将类型'MyNamespace.System.TCountryID'转换为'int'

实现了IConvertable接口之后,我会认为这已得到解决?

2.1)无法将类型'int'隐式转换为'MyNameSpace.System.TCountryID'2.2)无法将类型'MyNameSpace.System.TCountryID'隐式转换为'int'

如何解决2.x问题?

TIA

结构代码如下:

    [Serializable]
    [System.Runtime.InteropServices.ComVisible(true)]
    public struct TCountryID : IFormattable, IConvertible, IComparable, IComparable<TCountryID>, IEquatable<TCountryID>
    {
        #region Private Members
        private int FValue;                      //Base type we are encapsulating
        #endregion

        #region Public Members

        public override int GetHashCode()
        {
            return FValue;
        }

        #region IConvertible
        public TypeCode GetTypeCode()
        {
            return TypeCode.Int32;
        }

        bool IConvertible.ToBoolean(IFormatProvider AProvider)
        {
            return System.Convert.ToBoolean(FValue);
        }

        byte IConvertible.ToByte(IFormatProvider AProvider)
        {
            return System.Convert.ToByte(FValue);
        }

        char IConvertible.ToChar(IFormatProvider AProvider)
        {
            return Convert.ToChar(FValue);
        }

        DateTime IConvertible.ToDateTime(IFormatProvider AProvider)
        {
            return System.Convert.ToDateTime(FValue);
        }

        decimal IConvertible.ToDecimal(IFormatProvider AProvider)
        {
            return System.Convert.ToDecimal(FValue);
        }

        double IConvertible.ToDouble(IFormatProvider AProvider)
        {
            return System.Convert.ToDouble(FValue);
        }

        short IConvertible.ToInt16(IFormatProvider AProvider)
        {
            return System.Convert.ToInt16(FValue);
        }

        int IConvertible.ToInt32(IFormatProvider AProvider)
        {
            return System.Convert.ToInt32(FValue) ;
        }

        long IConvertible.ToInt64(IFormatProvider AProvider)
        {
            return System.Convert.ToInt64(FValue);
        }

        sbyte IConvertible.ToSByte(IFormatProvider AProvider)
        {
            return System.Convert.ToSByte(FValue);
        }

        float IConvertible.ToSingle(IFormatProvider AProvider)
        {
            return System.Convert.ToSingle(FValue);
        }

        object IConvertible.ToType(Type ATargetType, IFormatProvider AProvider)
        {
            if (ATargetType == null)
                throw new ArgumentNullException("ATargetType");

            return System.Convert.ChangeType(FValue, ATargetType, AProvider);
        }

        ushort IConvertible.ToUInt16(IFormatProvider AProvider)
        {
            return System.Convert.ToUInt16(FValue);
        }

        uint IConvertible.ToUInt32(IFormatProvider AProvider)
        {
            return System.Convert.ToUInt32(FValue);
        }

        ulong IConvertible.ToUInt64(IFormatProvider AProvider)
        {
            return System.Convert.ToUInt64(FValue);
        }

        #endregion
        #region IComparable
        public int CompareTo(object AValue)
        {
            TCountryID tcidTmp = (TCountryID)AValue;

            if (AValue == null)
                return 1;

            if (!(AValue is System.Int32))
                throw new ArgumentException("Value is not a System.Int32");

            if (FValue == tcidTmp.FValue)
                return 0;

            if (FValue > tcidTmp.FValue)
                return 1;
            else
                return -1;
        }

        public int CompareTo(TCountryID AValue)
        {
            if (FValue == AValue.FValue)
                return 0;

            if (FValue > AValue.FValue)
                return 1;
            else return -1;
        }
#endregion
        #region IEquatable
        public bool Equals(TCountryID obj)
        {
            return obj.FValue == FValue;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is System.TCountryID))
                return false;

            return ((TCountryID)obj).FValue == FValue;
        }
        #endregion
        #region IFormattable
        public override string ToString()
        {
            return FValue.ToString();
        }

        public string ToString(IFormatProvider AProvider)
        {
            return FValue.ToString(AProvider);
        }

        public string ToString(string AFormat)
        {
            return FValue.ToString(AFormat, null);
        }

        public string ToString(string AFormat, IFormatProvider AProvider)
        {
            return FValue.ToString(AFormat, AProvider);
        }
        #endregion
        #endregion
    }

不,C#语言对IConvertible接口一无所知。 仅当您调用Convert.ToType或其他方法时,它才起作用。

如果要允许与int转换,则需要在您的类型内明确提供它们:

public static implicit operator int(TCountryID id)
{
    return FValue; 
}

public static implicit operator TCountryID(int id)
{
    return new TCountryID(id); // You'll need to create this constructor...
}

个人而言,在执行此操作之前,我会认真考虑-如果您不小心,隐式转换会使代码的可读性降低。 (我还建议您不要将其称为TCountryID - T前缀不遵循.NET命名约定。对于字段使用F前缀也很奇怪,IMO。)

在文档中:“公共语言运行库通常通过Convert类公开IConvertible接口。在显式接口实现中,公共语言运行库还内部使用IConvertible接口,以简化用于支持Convert类和基本公共类中的转换的代码。语言运行时类型”。

因此,您仍然需要调用Convert。 例如:

int iTest = 0;
TCountryID tcidTest;
iTest = Convert.ToInt32(tcidTest);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM