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

本文关键字:不起作用 声明 类型 自定义 | 更新日期: 2023-09-27 18:04:25

G'Day,

对帖子的长度表示歉意,但代码是必要的。

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

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

1( 无法转换类型"MyNamespace"。系统TCountryID'到'int'

在实现了IConvertable接口后,我会认为这已经得到了处理?

2.1(无法将类型"int"隐式转换为"MyNameSpace"。系统TCountryID'2.2(无法隐式转换类型"MyNameSpace"。系统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#自定义类型声明-不起作用

不,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类公开IConvertable接口。在显式接口实现中,公共语言运行库还在内部使用IConverable接口,以简化用于支持Convert类和基本公共语言运行时类型中的转换的代码"。

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

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