Поделиться через


Convert.ChangeType Метод

Определение

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту.

Перегрузки

ChangeType(Object, Type)

Возвращает объект указанного типа и значение которого эквивалентно указанному объекту.

ChangeType(Object, TypeCode)

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту.

ChangeType(Object, Type, IFormatProvider)

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту. Параметр предоставляет сведения о форматировании, зависящие от языка и региональных параметров.

ChangeType(Object, TypeCode, IFormatProvider)

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту. Параметр предоставляет сведения о форматировании, зависящие от языка и региональных параметров.

ChangeType(Object, Type)

Исходный код:
Convert.cs
Исходный код:
Convert.cs
Исходный код:
Convert.cs

Возвращает объект указанного типа и значение которого эквивалентно указанному объекту.

public:
 static System::Object ^ ChangeType(System::Object ^ value, Type ^ conversionType);
public static object ChangeType (object value, Type conversionType);
public static object? ChangeType (object? value, Type conversionType);
static member ChangeType : obj * Type -> obj
Public Shared Function ChangeType (value As Object, conversionType As Type) As Object

Параметры

value
Object

Объект, реализующий интерфейс IConvertible.

conversionType
Type

Тип возвращаемого объекта.

Возвращаемое значение

Объект, тип которого conversionType и значение которого эквивалентно value.

-или-

Ссылка null (Nothing в Visual Basic), если valuenull и conversionType не является типом значения.

Исключения

Это преобразование не поддерживается.

-или-

value null, а conversionType — это тип значения.

-или-

value не реализует интерфейс IConvertible.

value не находится в формате, распознаваемом conversionType.

value представляет число, которое выходит за пределы диапазона conversionType.

conversionType null.

Примеры

В следующем примере показано использование метода ChangeType.

using namespace System;

int main()
{
   Double d = -2.345;
   int i =  *safe_cast<Int32^>(Convert::ChangeType( d, int::typeid ));
   Console::WriteLine( "The double value {0} when converted to an int becomes {1}", d, i );
   String^ s = "12/12/98";
   DateTime dt =  *safe_cast<DateTime^>(Convert::ChangeType( s, DateTime::typeid ));
   Console::WriteLine( "The string value {0} when converted to a Date becomes {1}", s, dt );
}
using System;

public class ChangeTypeTest {
    public static void Main() {

        Double d = -2.345;
        int i = (int)Convert.ChangeType(d, typeof(int));

        Console.WriteLine("The double value {0} when converted to an int becomes {1}", d, i);

        string s = "12/12/98";
        DateTime dt = (DateTime)Convert.ChangeType(s, typeof(DateTime));

        Console.WriteLine("The string value {0} when converted to a Date becomes {1}", s, dt);
    }
}
open System

let d = -2.345
let i = Convert.ChangeType(d, typeof<int>) :?> int

printfn $"The double value {d} when converted to an int becomes {i}"

let s = "12/12/98"
let dt = Convert.ChangeType(s, typeof<DateTime>) :?> DateTime

printfn $"The string value {s} when converted to a Date becomes {dt}"
Public Class ChangeTypeTest
    
    Public Shared Sub Main()
        Dim d As [Double] = - 2.345
        Dim i As Integer = CInt(Convert.ChangeType(d, GetType(Integer)))
        
        Console.WriteLine("The double value {0} when converted to an int becomes {1}", d, i)
        Dim s As String = "12/12/98"
        Dim dt As DateTime = CType(Convert.ChangeType(s, GetType(DateTime)), DateTime)
        
        Console.WriteLine("The string value {0} when converted to a Date becomes {1}", s, dt)
    End Sub
End Class

Комментарии

ChangeType — это метод преобразования общего назначения, который преобразует объект, указанный value в conversionType. Параметр value может быть объектом любого типа, и conversionType также может быть объектом Type, который представляет любой базовый или настраиваемый тип. Для успешного преобразования value необходимо реализовать интерфейс IConvertible, так как метод просто упаковывает вызов к соответствующему методу IConvertible. Для этого метода требуется, чтобы преобразование value в conversionType поддерживаться.

Этот метод использует язык и региональные параметры текущего потока для преобразования.

Примечания для тех, кто вызывает этот метод

Метод ChangeType(Object, Type) может преобразовать значение перечисления в другой тип. Однако он не может преобразовать другой тип в значение перечисления, даже если исходный тип является базовым типом перечисления. Чтобы преобразовать тип в значение перечисления, используйте оператор приведения (в C#) или функцию преобразования (в Visual Basic). В следующем примере показано преобразование в значение перечисления Continent и из нее.

using System;

public enum Continent
{
   Africa, Antarctica, Asia, Australia, Europe,
   NorthAmerica, SouthAmerica
};

public class Example
{
   public static void Main()
   {
      // Convert a Continent to a Double.
      Continent cont = Continent.NorthAmerica;
      Console.WriteLine("{0:N2}",
                        Convert.ChangeType(cont, typeof(Double)));

      // Convert a Double to a Continent.
      Double number = 6.0;
      try {
         Console.WriteLine("{0}",
                           Convert.ChangeType(number, typeof(Continent)));
      }
      catch (InvalidCastException) {
         Console.WriteLine("Cannot convert a Double to a Continent");
      }

      Console.WriteLine("{0}", (Continent) number);
   }
}
// The example displays the following output:
//       5.00
//       Cannot convert a Double to a Continent
//       SouthAmerica
open System

type Continent =
    | Africa = 0
    | Antarctica = 1
    | Asia = 2
    | Australia = 3
    | Europe = 4
    | NorthAmerica = 5
    | SouthAmerica = 6

// Convert a Continent to a Double.
let cont = Continent.NorthAmerica
printfn $"{Convert.ChangeType(cont, typeof<Double>):N2}"

// Convert a Double to a Continent.
let number = 6.0
try
    printfn $"{Convert.ChangeType(number, typeof<Continent>)}"
with :? InvalidCastException ->
    printfn "Cannot convert a Double to a Continent"

printfn $"{int number |> enum<Continent>}"
// The example displays the following output:
//       5.00
//       Cannot convert a Double to a Continent
//       SouthAmerica
Public Enum Continent As Integer
   Africa = 0
   Antarctica = 1
   Asia = 2
   Australia = 3
   Europe = 4
   NorthAmerica = 5
   SouthAmerica = 6
End Enum

Module Example
   Public Sub Main()
      ' Convert a Continent to a Double.
      Dim cont As Continent = Continent.NorthAmerica
      Console.WriteLine("{0:N2}", 
                        Convert.ChangeType(cont, GetType(Double)))
   
      ' Convert a Double to a Continent.
      Dim number As Double = 6.0
      Try
         Console.WriteLine("{0}", 
                           Convert.ChangeType(number, GetType(Continent)))
      Catch e As InvalidCastException
         Console.WriteLine("Cannot convert a Double to a Continent")
      End Try
      
      Console.WriteLine("{0}", CType(number, Continent))   
   End Sub
End Module
' The example displays the following output:
'    5.00
'    Cannot convert a Double to a Continent
'    SouthAmerica

Метод ChangeType(Object, Type) может преобразовать тип, допускающий значение NULL, в другой тип. Однако он не может преобразовать другой тип в значение типа, допускающего значение NULL, даже если conversionType является базовым типом Nullable<T>. Для выполнения преобразования можно использовать оператор приведения (в C#) или функцию преобразования (в Visual Basic). В следующем примере показано преобразование в тип, допускающий значение NULL, и из нее.

using System;

public class Example
{
   public static void Main()
   {
      int? intValue1 = 12893;
      double dValue1 = (double) Convert.ChangeType(intValue1, typeof(Double));
      Console.WriteLine("{0} ({1})--> {2} ({3})", intValue1, intValue1.GetType().Name,
                        dValue1, dValue1.GetType().Name);

      float fValue1 = 16.3478f;
      int? intValue2 = (int) fValue1;
      Console.WriteLine("{0} ({1})--> {2} ({3})", fValue1, fValue1.GetType().Name,
                        intValue2, intValue2.GetType().Name);
   }
}
// The example displays the following output:
//    12893 (Int32)--> 12893 (Double)
//    16.3478 (Single)--> 16 (Int32)
open System

let intValue1 = Nullable 12893
let dValue1 = Convert.ChangeType(intValue1, typeof<Double>) :?> double
printfn $"{intValue1} ({intValue1.GetType().Name})--> {dValue1} ({dValue1.GetType().Name})" 

let fValue1 = 16.3478f
let intValue2 = Nullable(int fValue1)
printfn $"{fValue1} ({fValue1.GetType().Name})--> {intValue2} ({intValue2.GetType().Name})"

// The example displays the following output:
//    12893 (Int32)--> 12893 (Double)
//    16.3478 (Single)--> 16 (Int32)
Module Example
   Public Sub Main()
      Dim intValue1 As Integer? = 12893
      Dim dValue1 As Double = CType(Convert.ChangeType(intValue1, GetType(Double)), Double)
      Console.WriteLine("{0} ({1})--> {2} ({3})", intValue1, intValue1.GetType().Name,
                        dValue1, dValue1.GetType().Name)
      

      Dim fValue1 As Single = 16.3478
      Dim intValue2 As Integer? = CType(fValue1, Integer) 
      Console.WriteLine("{0} ({1})--> {2} ({3})", fValue1, fValue1.GetType().Name,
                        intValue2, intValue2.GetType().Name)
   End Sub
End Module
' The example displays the following output:
'       12893 (Int32)--> 12893 (Double)
'       16.3478 (Single)--> 16 (Int32)

Применяется к

ChangeType(Object, TypeCode)

Исходный код:
Convert.cs
Исходный код:
Convert.cs
Исходный код:
Convert.cs

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту.

public:
 static System::Object ^ ChangeType(System::Object ^ value, TypeCode typeCode);
public static object? ChangeType (object? value, TypeCode typeCode);
public static object ChangeType (object value, TypeCode typeCode);
static member ChangeType : obj * TypeCode -> obj
Public Shared Function ChangeType (value As Object, typeCode As TypeCode) As Object

Параметры

value
Object

Объект, реализующий интерфейс IConvertible.

typeCode
TypeCode

Тип возвращаемого объекта.

Возвращаемое значение

Объект, базовый тип которого typeCode и значение которого эквивалентно value.

-или-

Пустая ссылка (Nothing в Visual Basic), если valuenull и typeCodeEmpty, Stringили Object.

Исключения

Это преобразование не поддерживается.

-или-

value null и typeCode указывает тип значения.

-или-

value не реализует интерфейс IConvertible.

value не находится в формате, распознаваемом типом typeCode.

value представляет число, которое выходит за пределы диапазона типа typeCode.

typeCode недопустимо.

Примеры

В следующем примере показано, как использовать метод ChangeType(Object, TypeCode) для изменения Object типа, указанного параметром TypeCode, если это возможно.

using namespace System;

void main()
{
   Double d = -2.345;
   int i = (int) Convert::ChangeType(d, TypeCode::Int32);

   Console::WriteLine("The Double {0} when converted to an Int32 is {1}", d, i);

   String^ s = "12/12/2009";
   DateTime dt = (DateTime)Convert::ChangeType(s, DateTime::typeid);

   Console::WriteLine("The String {0} when converted to a Date is {1}", s, dt);        
}
// The example displays the following output:
//    The Double -2.345 when converted to an Int32 is -2
//    The String 12/12/2009 when converted to a Date is 12/12/2009 12:00:00 AM
using System;

public class ChangeTypeTest {
    public static void Main() {

        Double d = -2.345;
        int i = (int)Convert.ChangeType(d, TypeCode.Int32);

        Console.WriteLine("The Double {0} when converted to an Int32 is {1}", d, i);

        string s = "12/12/2009";
        DateTime dt = (DateTime)Convert.ChangeType(s, typeof(DateTime));

        Console.WriteLine("The String {0} when converted to a Date is {1}", s, dt);
    }
}
// The example displays the following output:
//    The Double -2.345 when converted to an Int32 is -2
//    The String 12/12/2009 when converted to a Date is 12/12/2009 12:00:00 AM
open System

let d = -2.345
let i = Convert.ChangeType(d, TypeCode.Int32) :?> int

printfn $"The Double {d} when converted to an Int32 is {i}"

let s = "12/12/2009"
let dt = Convert.ChangeType(s, typeof<DateTime>) :?> DateTime

printfn $"The String {s} when converted to a Date is {dt}"
// The example displays the following output:
//    The Double -2.345 when converted to an Int32 is -2
//    The String 12/12/2009 when converted to a Date is 12/12/2009 12:00:00 AM
Public Class ChangeTypeTest
    
    Public Shared Sub Main()
        Dim d As [Double] = - 2.345
        Dim i As Integer = CInt(Convert.ChangeType(d, TypeCode.Int32))
        
        Console.WriteLine("The Double {0} when converted to an Int32 is {1}", d, i)
        Dim s As String = "12/12/2009"
        Dim dt As DateTime = CDate(Convert.ChangeType(s, TypeCode.DateTime))
        
        Console.WriteLine("The String {0} when converted to a Date is {1}", s, dt)
    End Sub 
End Class 
' The example displays the following output:
'    The Double -2.345 when converted to an Int32 is -2
'    The String 12/12/2009 when converted to a Date is 12/12/2009 12:00:00 AM

Комментарии

ChangeType(Object, TypeCode) — это метод преобразования общего назначения, который преобразует объект, указанный value в предопределенный тип, указанный typeCode. Параметр value может быть объектом любого типа. Для успешного преобразования value необходимо реализовать интерфейс IConvertible, так как метод просто упаковывает вызов к соответствующему методу IConvertible. Этот метод также требует поддержки преобразования value в typeCode.

Метод ChangeType(Object, TypeCode) не поддерживает преобразование value в пользовательский тип. Чтобы выполнить такое преобразование, вызовите метод ChangeType(Object, Type).

Применяется к

ChangeType(Object, Type, IFormatProvider)

Исходный код:
Convert.cs
Исходный код:
Convert.cs
Исходный код:
Convert.cs

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту. Параметр предоставляет сведения о форматировании, зависящие от языка и региональных параметров.

public:
 static System::Object ^ ChangeType(System::Object ^ value, Type ^ conversionType, IFormatProvider ^ provider);
public static object ChangeType (object value, Type conversionType, IFormatProvider provider);
public static object? ChangeType (object? value, Type conversionType, IFormatProvider? provider);
static member ChangeType : obj * Type * IFormatProvider -> obj
Public Shared Function ChangeType (value As Object, conversionType As Type, provider As IFormatProvider) As Object

Параметры

value
Object

Объект, реализующий интерфейс IConvertible.

conversionType
Type

Тип возвращаемого объекта.

provider
IFormatProvider

Объект, предоставляющий сведения о форматировании, зависящее от языка и региональных параметров.

Возвращаемое значение

Объект, тип которого conversionType и значение которого эквивалентно value.

-или-

value, если Typevalue и conversionType равны.

-или-

Ссылка null (Nothing в Visual Basic), если valuenull и conversionType не является типом значения.

Исключения

Это преобразование не поддерживается.

-или-

value null, а conversionType — это тип значения.

-или-

value не реализует интерфейс IConvertible.

value не в формате conversionType распознается provider.

value представляет число, которое выходит за пределы диапазона conversionType.

conversionType null.

Примеры

В следующем примере определяется класс Temperature, реализующий интерфейс IConvertible.

using namespace System;
using namespace System::Globalization;

public ref class Temperature : IConvertible
{
private:
   Decimal m_Temp;

public:
   Temperature(Decimal temperature)
   {
      m_Temp = temperature;
   }
   
   property Decimal Celsius {
      Decimal get() { return m_Temp; }
   }
   
   property Decimal Kelvin {
      Decimal get() { return m_Temp + (Decimal) 273.15; }
   }
   
   property Decimal Fahrenheit {
      Decimal get() { return Math::Round((Decimal) (m_Temp * 9 / 5 + 32), 2); }
   }
   
   virtual String^ ToString()
   override {
      return m_Temp.ToString("N2") + "�C";
   }

   // IConvertible implementations.
   virtual TypeCode GetTypeCode()
   {
      return TypeCode::Object;
   }
   
   virtual bool ToBoolean(IFormatProvider^ provider) 
   {
      if (m_Temp == 0)
         return false;
      else
         return true;
   } 
   
   virtual Byte ToByte(IFormatProvider^ provider)
   {
      if (m_Temp < Byte::MinValue || m_Temp > Byte::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the Byte type.", 
                                                   m_Temp));
      else
         return Decimal::ToByte(m_Temp);
   }
   
   virtual Char ToChar(IFormatProvider^ provider)
   {
      throw gcnew InvalidCastException("Temperature to Char conversion is not supported.");
   } 
   
   virtual DateTime ToDateTime(IFormatProvider^ provider)
   {
      throw gcnew InvalidCastException("Temperature to DateTime conversion is not supported.");
   }
   
   virtual Decimal ToDecimal(IFormatProvider^ provider)
   {
      return m_Temp;
   }
   
   virtual Double ToDouble(IFormatProvider^ provider)
   {
      return Decimal::ToDouble(m_Temp);
   }   
   
   virtual Int16 ToInt16(IFormatProvider^ provider)
   {
      if (m_Temp < Int16::MinValue || m_Temp > Int16::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the Int16 type.",
                                                   m_Temp));
      else
         return Decimal::ToInt16(m_Temp);
   }
   
   virtual Int32 ToInt32(IFormatProvider^ provider)
      {
      if (m_Temp < Int32::MinValue || m_Temp > Int32::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the Int32 type.",
                                                   m_Temp));
      else
         return Decimal::ToInt32(m_Temp);
   }
   
   virtual Int64 ToInt64(IFormatProvider^ provider)
   {
      if (m_Temp < Int64::MinValue || m_Temp > Int64::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the Int64 type.",
                                                   m_Temp));
      else
         return Decimal::ToInt64(m_Temp);
   }
   
   virtual SByte ToSByte(IFormatProvider^ provider)
   {
      if (m_Temp < SByte::MinValue || m_Temp > SByte::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the SByte type.",
                                                   m_Temp));
      else
         return Decimal::ToSByte(m_Temp);
   }

   virtual Single ToSingle(IFormatProvider^ provider)
   {
      return Decimal::ToSingle(m_Temp);
   }

   virtual String^ ToString(IFormatProvider^ provider)
   {
      return m_Temp.ToString("N2", provider) + "�C";
   }
   
   virtual Object^ ToType(Type^ conversionType, IFormatProvider^ provider)
   {
      switch (Type::GetTypeCode(conversionType))
      {
      case TypeCode::Boolean: 
            return ToBoolean(nullptr);
      case TypeCode::Byte:
            return ToByte(nullptr);
      case TypeCode::Char:
            return ToChar(nullptr);
      case TypeCode::DateTime:
            return ToDateTime(nullptr);
      case TypeCode::Decimal:
            return ToDecimal(nullptr);
      case TypeCode::Double:
            return ToDouble(nullptr);
      case TypeCode::Int16:
            return ToInt16(nullptr);
      case TypeCode::Int32:
            return ToInt32(nullptr);
      case TypeCode::Int64:
            return ToInt64(nullptr);
      case TypeCode::Object:
            if (Temperature::typeid->Equals(conversionType))
               return this;
            else
               throw gcnew InvalidCastException(String::Format("Conversion to a {0} is not supported.",
                                                            conversionType->Name));
      case TypeCode::SByte:
            return ToSByte(nullptr);
      case TypeCode::Single:
            return ToSingle(nullptr);
      case TypeCode::String:
            return ToString(provider);
      case TypeCode::UInt16:
            return ToUInt16(nullptr);
      case TypeCode::UInt32:
            return ToUInt32(nullptr);
      case TypeCode::UInt64:
            return ToUInt64(nullptr);   
         default:
            throw gcnew InvalidCastException(String::Format("Conversion to {0} is not supported.", conversionType->Name));   
      }
   }
   
   virtual UInt16 ToUInt16(IFormatProvider^ provider)
   {
      if (m_Temp < UInt16::MinValue || m_Temp > UInt16::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the UInt16 type.",
                                                   m_Temp));
      else
         return Decimal::ToUInt16(m_Temp);
   }

   virtual UInt32 ToUInt32(IFormatProvider^ provider)
   {
      if (m_Temp < UInt32::MinValue || m_Temp > UInt32::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the UInt32 type.",
                                                   m_Temp));
      else
         return Decimal::ToUInt32(m_Temp);
   }
   
   virtual UInt64 ToUInt64(IFormatProvider^ provider)
   {
      if (m_Temp < UInt64::MinValue || m_Temp > UInt64::MaxValue)
         throw gcnew OverflowException(String::Format("{0} is out of range of the UInt64 type.",
                                                   m_Temp));
      else
         return Decimal::ToUInt64(m_Temp);
   }
};
using System;
using System.Globalization;

public class Temperature : IConvertible
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }
   }

   public decimal Fahrenheit
   {
      get { return Math.Round((decimal) (this.m_Temp * 9 / 5 + 32), 2); }
   }

   public override string ToString()
   {
      return m_Temp.ToString("N2") + "°C";
   }

   // IConvertible implementations.
   public TypeCode GetTypeCode()
   {
      return TypeCode.Object;
   }

   public bool ToBoolean(IFormatProvider provider)
   {
      if (m_Temp == 0)
         return false;
      else
         return true;
   }

   public byte ToByte(IFormatProvider provider)
   {
      if (m_Temp < Byte.MinValue || m_Temp > Byte.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the Byte type.",
                                                   this.m_Temp));
      else
         return Decimal.ToByte(this.m_Temp);
   }

   public char ToChar(IFormatProvider provider)
   {
      throw new InvalidCastException("Temperature to Char conversion is not supported.");
   }

   public DateTime ToDateTime(IFormatProvider provider)
   {
      throw new InvalidCastException("Temperature to DateTime conversion is not supported.");
   }

   public decimal ToDecimal(IFormatProvider provider)
   {
      return this.m_Temp;
   }

   public double ToDouble(IFormatProvider provider)
   {
      return Decimal.ToDouble(this.m_Temp);
   }

   public short ToInt16(IFormatProvider provider)
   {
      if (this.m_Temp < Int16.MinValue || this.m_Temp > Int16.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the Int16 type.",
                                                   this.m_Temp));
      else
         return Decimal.ToInt16(this.m_Temp);
   }

   public int ToInt32(IFormatProvider provider)
      {
      if (this.m_Temp < Int32.MinValue || this.m_Temp > Int32.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the Int32 type.",
                                                   this.m_Temp));
      else
         return Decimal.ToInt32(this.m_Temp);
   }

   public long ToInt64(IFormatProvider provider)
   {
      if (this.m_Temp < Int64.MinValue || this.m_Temp > Int64.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the Int64 type.",
                                                   this.m_Temp));
      else
         return Decimal.ToInt64(this.m_Temp);
   }

   public sbyte ToSByte(IFormatProvider provider)
   {
      if (this.m_Temp < SByte.MinValue || this.m_Temp > SByte.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the SByte type.",
                                                   this.m_Temp));
      else
         return Decimal.ToSByte(this.m_Temp);
   }

   public float ToSingle(IFormatProvider provider)
   {
      return Decimal.ToSingle(this.m_Temp);
   }

   public string ToString(IFormatProvider provider)
   {
      return m_Temp.ToString("N2", provider) + "°C";
   }

   public object ToType(Type conversionType, IFormatProvider provider)
   {
      switch (Type.GetTypeCode(conversionType))
      {
         case TypeCode.Boolean:
            return this.ToBoolean(null);
         case TypeCode.Byte:
            return this.ToByte(null);
         case TypeCode.Char:
            return this.ToChar(null);
         case TypeCode.DateTime:
            return this.ToDateTime(null);
         case TypeCode.Decimal:
            return this.ToDecimal(null);
         case TypeCode.Double:
            return this.ToDouble(null);
         case TypeCode.Int16:
            return this.ToInt16(null);
         case TypeCode.Int32:
            return this.ToInt32(null);
         case TypeCode.Int64:
            return this.ToInt64(null);
         case TypeCode.Object:
            if (typeof(Temperature).Equals(conversionType))
               return this;
            else
               throw new InvalidCastException(String.Format("Conversion to a {0} is not supported.",
                                                            conversionType.Name));
         case TypeCode.SByte:
            return this.ToSByte(null);
         case TypeCode.Single:
            return this.ToSingle(null);
         case TypeCode.String:
            return this.ToString(provider);
         case TypeCode.UInt16:
            return this.ToUInt16(null);
         case TypeCode.UInt32:
            return this.ToUInt32(null);
         case TypeCode.UInt64:
            return this.ToUInt64(null);
         default:
            throw new InvalidCastException(String.Format("Conversion to {0} is not supported.", conversionType.Name));
      }
   }

   public ushort ToUInt16(IFormatProvider provider)
   {
      if (this.m_Temp < UInt16.MinValue || this.m_Temp > UInt16.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the UInt16 type.",
                                                   this.m_Temp));
      else
         return Decimal.ToUInt16(this.m_Temp);
   }

   public uint ToUInt32(IFormatProvider provider)
   {
      if (this.m_Temp < UInt32.MinValue || this.m_Temp > UInt32.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the UInt32 type.",
                                                   this.m_Temp));
      else
         return Decimal.ToUInt32(this.m_Temp);
   }

   public ulong ToUInt64(IFormatProvider provider)
   {
      if (this.m_Temp < UInt64.MinValue || this.m_Temp > UInt64.MaxValue)
         throw new OverflowException(String.Format("{0} is out of range of the UInt64 type.",
                                                   this.m_Temp));
      else
         return Decimal.ToUInt64(this.m_Temp);
   }
}
open System
open System.Globalization

type Temperature(temperature: decimal) = 

    member _.Celsius = temperature

    member _.Kelvin =
        temperature + 273.15m

    member _.Fahrenheit =
        Math.Round(decimal (temperature * 9m / 5m + 32m), 2)

    override _.ToString() =
        temperature.ToString "N2" + "°C"

    // IConvertible implementations.
    interface IConvertible with
        member _.GetTypeCode() =
            TypeCode.Object

        member _.ToBoolean(provider: IFormatProvider) =
            temperature <> 0M

        member _.ToByte(provider: IFormatProvider) =
            if temperature < decimal Byte.MinValue || temperature > decimal Byte.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the Byte type.")
            else
                Decimal.ToByte temperature

        member _.ToChar(provider: IFormatProvider) =
            raise (InvalidCastException "Temperature to Char conversion is not supported.")

        member _.ToDateTime(provider: IFormatProvider) =
            raise (InvalidCastException "Temperature to DateTime conversion is not supported.")

        member _.ToDecimal(provider: IFormatProvider) =
            temperature

        member _.ToDouble(provider: IFormatProvider) =
            Decimal.ToDouble temperature

        member _.ToInt16(provider: IFormatProvider) =
            if temperature < decimal Int16.MinValue || temperature > decimal Int16.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the Int16 type.")
            else
                Decimal.ToInt16 temperature

        member _.ToInt32(provider: IFormatProvider) =
            if temperature < decimal Int32.MinValue || temperature > decimal Int32.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the Int32 type.")
            else
                Decimal.ToInt32 temperature

        member _.ToInt64(provider: IFormatProvider) =
            if temperature < decimal Int64.MinValue || temperature > decimal Int64.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the Int64 type.")
            else
                Decimal.ToInt64 temperature

        member _.ToSByte(provider: IFormatProvider) =
            if temperature < decimal SByte.MinValue || temperature > decimal SByte.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the SByte type.")
            else
                Decimal.ToSByte temperature

        member _.ToSingle(provider: IFormatProvider) =
            Decimal.ToSingle temperature

        member _.ToString(provider: IFormatProvider) =
            temperature.ToString("N2", provider) + "°C"

        member this.ToType(conversionType: Type, provider: IFormatProvider) =
            let this = this :> IConvertible
            match Type.GetTypeCode conversionType with
            | TypeCode.Boolean->
                this.ToBoolean null
            | TypeCode.Byte ->
                this.ToByte null
            | TypeCode.Char ->
                this.ToChar null
            | TypeCode.DateTime ->
                this.ToDateTime null
            | TypeCode.Decimal ->
                this.ToDecimal null
            | TypeCode.Double ->
                this.ToDouble null
            | TypeCode.Int16 ->
                this.ToInt16 null
            | TypeCode.Int32 ->
                this.ToInt32 null
            | TypeCode.Int64 ->
                this.ToInt64 null
            | TypeCode.Object ->
                if typeof<Temperature>.Equals conversionType then
                    this
                else
                    raise (InvalidCastException $"Conversion to a {conversionType.Name} is not supported.")
            | TypeCode.SByte ->
                this.ToSByte null
            | TypeCode.Single ->
                this.ToSingle null
            | TypeCode.String ->
                this.ToString provider
            | TypeCode.UInt16 ->
                this.ToUInt16 null
            | TypeCode.UInt32->
                this.ToUInt32 null
            | TypeCode.UInt64->
                this.ToUInt64 null
            | _ ->
                raise (InvalidCastException $"Conversion to {conversionType.Name} is not supported.")

        member _.ToUInt16(provider: IFormatProvider) =
            if temperature < decimal UInt16.MinValue || temperature > decimal UInt16.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the UInt16 type.")
            else
                Decimal.ToUInt16 temperature

        member _.ToUInt32(provider: IFormatProvider) =
            if temperature < decimal UInt32.MinValue || temperature > decimal UInt32.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the UInt32 type.")
            else
                Decimal.ToUInt32 temperature

        member _.ToUInt64(provider: IFormatProvider) =
            if temperature < decimal UInt64.MinValue || temperature > decimal UInt64.MaxValue then
                raise (OverflowException $"{temperature} is out of range of the UInt64 type.")
            else
                Decimal.ToUInt64 temperature
Imports System.Globalization

Public Class Temperature : Implements IConvertible
   Private m_Temp As Decimal

   Public Sub New(temperature As Decimal)
      Me.m_Temp = temperature
   End Sub
   
   Public ReadOnly Property Celsius() As Decimal
      Get
         Return Me.m_Temp
      End Get   
   End Property
   
   Public ReadOnly Property Kelvin() As Decimal
      Get
         Return Me.m_Temp + 273.15d   
      End Get
   End Property
   
   Public ReadOnly Property Fahrenheit() As Decimal
      Get
         Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
      End Get      
   End Property
   
   Public Overrides Function ToString() As String
      Return m_Temp.ToString("N2") & "°C"
   End Function

   ' IConvertible implementations.
   Public Function GetTypeCode() As TypeCode _
                   Implements IConvertible.GetTypeCode
      Return TypeCode.Object
   End Function
   
   Public Function ToBoolean(provider As IFormatProvider) As Boolean _
                   Implements IConvertible.ToBoolean
      If m_Temp = 0 Then
         Return False
      Else
         Return True
      End If
   End Function 
   
   Public Function ToByte(provider As IFormatProvider) As Byte _
                   Implements IConvertible.ToByte
      If m_Temp < Byte.MinValue Or m_Temp > Byte.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the Byte type.", _ 
                                                   Me.m_Temp)) 
      Else
         Return Decimal.ToByte(Me.m_Temp)
      End If       
   End Function
   
   Public Function ToChar(provider As IFormatProvider) As Char _
                   Implements IConvertible.ToChar
      Throw New InvalidCastException("Temperature to Char conversion is not supported.")
   End Function 
   
   Public Function ToDateTime(provider As IFormatProvider) As Date _
                   Implements IConvertible.ToDateTime
      Throw New InvalidCastException("Temperature to DateTime conversion is not supported.")
   End Function
   
   Public Function ToDecimal(provider As IFormatProvider) As Decimal _
                   Implements IConvertible.ToDecimal
      Return Me.m_Temp
   End Function
   
   Public Function ToDouble(provider As IFormatProvider) As Double _
                   Implements IConvertible.ToDouble
      Return Decimal.ToDouble(Me.m_Temp)
   End Function   
   
   Public Function ToInt16(provider As IFormatProvider) As Int16 _
                   Implements IConvertible.ToInt16
      If Me.m_Temp < Int16.MinValue Or Me.m_Temp > Int16.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the Int16 type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToInt16(Me.m_Temp)   
      End If
   End Function
   
   Public Function ToInt32(provider As IFormatProvider) As Int32 _
                   Implements IConvertible.ToInt32
      If Me.m_Temp < Int32.MinValue Or Me.m_Temp > Int32.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the Int32 type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToInt32(Me.m_Temp)
      End If      
   End Function
   
   Public Function ToInt64(provider As IFormatProvider) As Int64 _
                   Implements IConvertible.ToInt64
      If Me.m_Temp < Int64.MinValue Or Me.m_Temp > Int64.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the Int64 type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToInt64(Me.m_Temp)
      End If      
   End Function
   
   Public Function ToSByte(provider As IFormatProvider) As SByte _
                   Implements IConvertible.ToSByte
      If Me.m_Temp < SByte.MinValue Or Me.m_Temp > SByte.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the SByte type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToSByte(Me.m_Temp)
      End If      
   End Function

   Public Function ToSingle(provider As IFormatProvider) As Single _
                   Implements IConvertible.ToSingle
      Return Decimal.ToSingle(Me.m_Temp)
   End Function

   Public Overloads Function ToString(provider As IFormatProvider) As String _
                   Implements IConvertible.ToString
      Return m_Temp.ToString("N2", provider) & "°C"
   End Function
   
   Public Function ToType(conversionType As Type, provider As IFormatProvider) As Object _
                   Implements IConvertible.ToType
      Select Case Type.GetTypeCode(conversionType)
         Case TypeCode.Boolean 
            Return Me.ToBoolean(Nothing)
         Case TypeCode.Byte
            Return Me.ToByte(Nothing)
         Case TypeCode.Char
            Return Me.ToChar(Nothing)
         Case TypeCode.DateTime
            Return Me.ToDateTime(Nothing)
         Case TypeCode.Decimal
            Return Me.ToDecimal(Nothing)
         Case TypeCode.Double
            Return Me.ToDouble(Nothing)
         Case TypeCode.Int16
            Return Me.ToInt16(Nothing)
         Case TypeCode.Int32
            Return Me.ToInt32(Nothing)
         Case TypeCode.Int64
            Return Me.ToInt64(Nothing)
         Case TypeCode.Object
            If GetType(Temperature).Equals(conversionType) Then
               Return Me
            Else
               Throw New InvalidCastException(String.Format("Conversion to a {0} is not supported.", _
                                                            conversionType.Name))
            End If 
         Case TypeCode.SByte
            Return Me.ToSByte(Nothing)
         Case TypeCode.Single
            Return Me.ToSingle(Nothing)
         Case TypeCode.String
            Return Me.ToString(provider)
         Case TypeCode.UInt16
            Return Me.ToUInt16(Nothing)
         Case TypeCode.UInt32
            Return Me.ToUInt32(Nothing)
         Case TypeCode.UInt64
            Return Me.ToUInt64(Nothing)   
         Case Else
            Throw New InvalidCastException(String.Format("Conversion to {0} is not supported.", conversionType.Name))   
      End Select
   End Function
   
   Public Function ToUInt16(provider As IFormatProvider) As UInt16 _
                   Implements IConvertible.ToUInt16
      If Me.m_Temp < UInt16.MinValue Or Me.m_Temp > UInt16.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the UInt16 type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToUInt16(Me.m_Temp)
      End If   
   End Function

   Public Function ToUInt32(provider As IFormatProvider) As UInt32 _
                   Implements IConvertible.ToUInt32
      If Me.m_Temp < UInt32.MinValue Or Me.m_Temp > UInt32.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the UInt32 type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToUInt32(Me.m_Temp)
      End If   
   End Function
   
   Public Function ToUInt64(provider As IFormatProvider) As UInt64 _
                   Implements IConvertible.ToUInt64
      If Me.m_Temp < UInt64.MinValue Or Me.m_Temp > UInt64.MaxValue Then
         Throw New OverflowException(String.Format("{0} is out of range of the UInt64 type.", _
                                                   Me.m_Temp))
      Else
         Return Decimal.ToUInt64(Me.m_temp)
      End If   
   End Function
End Class

В следующем примере создается экземпляр класса Temperature и вызывается метод ChangeType(Object, Type, IFormatProvider) для преобразования его в базовые числовые типы, поддерживаемые .NET, и в String. В нем показано, что метод ChangeType упаковывает вызов IConvertible реализации исходного типа.

void main()
{     
   Temperature^ cool = gcnew Temperature(5);
   array<Type^>^ targetTypes = gcnew array<Type^> { SByte::typeid, Int16::typeid, Int32::typeid,
                                                    Int64::typeid, Byte::typeid, UInt16::typeid,
                                                    UInt32::typeid, UInt64::typeid, Decimal::typeid,
                                                    Single::typeid, Double::typeid, String::typeid };
   CultureInfo^ provider = gcnew CultureInfo("fr-FR");
      
   for each (Type^ targetType in targetTypes)
   {
      try {
         Object^ value = Convert::ChangeType(cool, targetType, provider);
         Console::WriteLine("Converted {0} {1} to {2} {3}.",
                           cool->GetType()->Name, cool->ToString(),
                           targetType->Name, value);
      }
      catch (InvalidCastException^) {
         Console::WriteLine("Unsupported {0} --> {1} conversion.",
                           cool->GetType()->Name, targetType->Name);
      }                     
      catch (OverflowException^) {
         Console::WriteLine("{0} is out of range of the {1} type.",
                           cool, targetType->Name);
      }
   }
}
// The example dosplays the following output:
//       Converted Temperature 5.00�C to SByte 5.
//       Converted Temperature 5.00�C to Int16 5.
//       Converted Temperature 5.00�C to Int32 5.
//       Converted Temperature 5.00�C to Int64 5.
//       Converted Temperature 5.00�C to Byte 5.
//       Converted Temperature 5.00�C to UInt16 5.
//       Converted Temperature 5.00�C to UInt32 5.
//       Converted Temperature 5.00�C to UInt64 5.
//       Converted Temperature 5.00�C to Decimal 5.
//       Converted Temperature 5.00�C to Single 5.
//       Converted Temperature 5.00�C to Double 5.
//       Converted Temperature 5.00�C to String 5,00�C.
public class Example
{
   public static void Main()
   {
      Temperature cool = new Temperature(5);
      Type[] targetTypes = { typeof(SByte), typeof(Int16), typeof(Int32),
                             typeof(Int64), typeof(Byte), typeof(UInt16),
                             typeof(UInt32), typeof(UInt64), typeof(Decimal),
                             typeof(Single), typeof(Double), typeof(String) };
      CultureInfo provider = new CultureInfo("fr-FR");

      foreach (Type targetType in targetTypes)
      {
         try {
            object value = Convert.ChangeType(cool, targetType, provider);
            Console.WriteLine("Converted {0} {1} to {2} {3}.",
                              cool.GetType().Name, cool.ToString(),
                              targetType.Name, value);
         }
         catch (InvalidCastException) {
            Console.WriteLine("Unsupported {0} --> {1} conversion.",
                              cool.GetType().Name, targetType.Name);
         }
         catch (OverflowException) {
            Console.WriteLine("{0} is out of range of the {1} type.",
                              cool, targetType.Name);
         }
      }
   }
}
// The example dosplays the following output:
//       Converted Temperature 5.00°C to SByte 5.
//       Converted Temperature 5.00°C to Int16 5.
//       Converted Temperature 5.00°C to Int32 5.
//       Converted Temperature 5.00°C to Int64 5.
//       Converted Temperature 5.00°C to Byte 5.
//       Converted Temperature 5.00°C to UInt16 5.
//       Converted Temperature 5.00°C to UInt32 5.
//       Converted Temperature 5.00°C to UInt64 5.
//       Converted Temperature 5.00°C to Decimal 5.
//       Converted Temperature 5.00°C to Single 5.
//       Converted Temperature 5.00°C to Double 5.
//       Converted Temperature 5.00°C to String 5,00°C.
let cool = Temperature 5
let targetTypes = 
    [ typeof<SByte>; typeof<Int16>; typeof<Int32>
      typeof<Int64>; typeof<Byte>; typeof<UInt16>
      typeof<UInt32>; typeof<UInt64>; typeof<Decimal>;
      typeof<Single>; typeof<Double>; typeof<String>; ]

let provider = CultureInfo "fr-FR"

for targetType in targetTypes do
    try
        let value = Convert.ChangeType(cool, targetType, provider)
        printfn $"Converted {cool.GetType().Name} {cool} to {targetType.Name} {value}."
    with
    | :? InvalidCastException ->
        printfn $"Unsupported {cool.GetType().Name} --> {targetType.Name} conversion."
    | :? OverflowException ->
        printfn $"{cool} is out of range of the {targetType.Name} type."

// The example dosplays the following output:
//       Converted Temperature 5.00°C to SByte 5.
//       Converted Temperature 5.00°C to Int16 5.
//       Converted Temperature 5.00°C to Int32 5.
//       Converted Temperature 5.00°C to Int64 5.
//       Converted Temperature 5.00°C to Byte 5.
//       Converted Temperature 5.00°C to UInt16 5.
//       Converted Temperature 5.00°C to UInt32 5.
//       Converted Temperature 5.00°C to UInt64 5.
//       Converted Temperature 5.00°C to Decimal 5.
//       Converted Temperature 5.00°C to Single 5.
//       Converted Temperature 5.00°C to Double 5.
//       Converted Temperature 5.00°C to String 5,00°C.
Module Example
   Public Sub Main()
      Dim cool As New Temperature(5)
      Dim targetTypes() As Type = { GetType(SByte), GetType(Int16), GetType(Int32), _
                                    GetType(Int64), GetType(Byte), GetType(UInt16), _
                                    GetType(UInt32), GetType(UInt64), GetType(Decimal), _
                                    GetType(Single), GetType(Double), GetType(String) }
      Dim provider As New CultureInfo("fr-FR")
      
      For Each targetType As Type In targetTypes
         Try
            Dim value As Object = Convert.ChangeType(cool, targetType, provider)
            Console.WriteLine("Converted {0} {1} to {2} {3}.", _
                              cool.GetType().Name, cool.ToString(), _
                              targetType.Name, value)
         Catch e As InvalidCastException
            Console.WriteLine("Unsupported {0} --> {1} conversion.", _
                              cool.GetType().Name, targetType.Name)
         Catch e As OverflowException
            Console.WriteLine("{0} is out of range of the {1} type.", _
                              cool, targetType.Name)
         End Try                     
      Next
   End Sub
End Module
' The example displays the following output:
'       Converted Temperature 5.00°C to SByte 5.
'       Converted Temperature 5.00°C to Int16 5.
'       Converted Temperature 5.00°C to Int32 5.
'       Converted Temperature 5.00°C to Int64 5.
'       Converted Temperature 5.00°C to Byte 5.
'       Converted Temperature 5.00°C to UInt16 5.
'       Converted Temperature 5.00°C to UInt32 5.
'       Converted Temperature 5.00°C to UInt64 5.
'       Converted Temperature 5.00°C to Decimal 5.
'       Converted Temperature 5.00°C to Single 5.
'       Converted Temperature 5.00°C to Double 5.
'       Converted Temperature 5.00°C to String 5,00°C.

Комментарии

ChangeType — это метод преобразования общего назначения, который преобразует объект, указанный value в conversionType. Параметр value может быть объектом любого типа, и conversionType также может быть объектом Type, который представляет любой базовый или настраиваемый тип. Для успешного преобразования value необходимо реализовать интерфейс IConvertible, так как метод просто упаковывает вызов к соответствующему методу IConvertible. Для этого метода требуется, чтобы преобразование value в conversionType поддерживаться.

Параметр provider — это реализация IFormatProvider, которая предоставляет сведения о форматировании для преобразования. Зависит ли этот параметр от базовой реализации IConvertible. Если value является базовым типом данных, provider используется только для следующих преобразований:

  • Преобразование из числа в строку или из строки в число. provider должен быть объектом CultureInfo, объектом NumberFormatInfo или пользовательской реализацией IFormatProvider, возвращающей объект NumberFormatInfo. Однако, поскольку метод ChangeType(Object, TypeCode, IFormatProvider) выполняет преобразование с помощью описателя формата G по умолчанию, параметр provider не действует, если value или целевой тип является целым числом без знака. Если providernull, используется объект CultureInfo, представляющий текущий язык и региональные параметры.

  • Преобразование из значения DateTime в строку или из строки в значение DateTime. provider должен быть объектом CultureInfo или DateTimeFormatInfo. Если providernull, используется объект CultureInfo, представляющий текущий язык и региональные параметры.

Если value является определяемым приложением типом, его реализация IConvertible может использовать параметр provider.

Примечания для тех, кто вызывает этот метод

Метод ChangeType(Object, Type, IFormatProvider) может преобразовать значение перечисления в другой тип. Однако он не может преобразовать другой тип в значение перечисления, даже если исходный тип является базовым типом перечисления. Чтобы преобразовать тип в значение перечисления, используйте оператор приведения (в C#) или функцию преобразования (в Visual Basic). В следующем примере показано преобразование в значение перечисления Continent и из нее.

using System;

public enum Continent
{
   Africa, Antarctica, Asia, Australia, Europe,
   NorthAmerica, SouthAmerica
};

public class Example
{
   public static void Main()
   {
      // Convert a Continent to a Double.
      Continent cont = Continent.NorthAmerica;
      Console.WriteLine("{0:N2}",
                        Convert.ChangeType(cont, typeof(Double)));

      // Convert a Double to a Continent.
      Double number = 6.0;
      try {
         Console.WriteLine("{0}",
                           Convert.ChangeType(number, typeof(Continent)));
      }
      catch (InvalidCastException) {
         Console.WriteLine("Cannot convert a Double to a Continent");
      }

      Console.WriteLine("{0}", (Continent) number);
   }
}
// The example displays the following output:
//       5.00
//       Cannot convert a Double to a Continent
//       SouthAmerica
open System

type Continent =
    | Africa = 0
    | Antarctica = 1
    | Asia = 2
    | Australia = 3
    | Europe = 4
    | NorthAmerica = 5
    | SouthAmerica = 6

// Convert a Continent to a Double.
let cont = Continent.NorthAmerica
printfn $"{Convert.ChangeType(cont, typeof<Double>):N2}"

// Convert a Double to a Continent.
let number = 6.0
try
    printfn $"{Convert.ChangeType(number, typeof<Continent>)}"
with :? InvalidCastException ->
    printfn "Cannot convert a Double to a Continent"

printfn $"{int number |> enum<Continent>}"
// The example displays the following output:
//       5.00
//       Cannot convert a Double to a Continent
//       SouthAmerica
Public Enum Continent As Integer
   Africa = 0
   Antarctica = 1
   Asia = 2
   Australia = 3
   Europe = 4
   NorthAmerica = 5
   SouthAmerica = 6
End Enum

Module Example
   Public Sub Main()
      ' Convert a Continent to a Double.
      Dim cont As Continent = Continent.NorthAmerica
      Console.WriteLine("{0:N2}", 
                        Convert.ChangeType(cont, GetType(Double)))
   
      ' Convert a Double to a Continent.
      Dim number As Double = 6.0
      Try
         Console.WriteLine("{0}", 
                           Convert.ChangeType(number, GetType(Continent)))
      Catch e As InvalidCastException
         Console.WriteLine("Cannot convert a Double to a Continent")
      End Try
      
      Console.WriteLine("{0}", CType(number, Continent))   
   End Sub
End Module
' The example displays the following output:
'    5.00
'    Cannot convert a Double to a Continent
'    SouthAmerica

Метод ChangeType(Object, Type, IFormatProvider) может преобразовать тип, допускающий значение NULL, в другой тип. Однако он не может преобразовать другой тип в значение типа, допускающего значение NULL, даже если conversionType является базовым типом Nullable<T>. Для выполнения преобразования можно использовать оператор приведения (в C#) или функцию преобразования (в Visual Basic). В следующем примере показано преобразование в тип, допускающий значение NULL, и из нее.

using System;

public class Example
{
   public static void Main()
   {
      int? intValue1 = 12893;
      double dValue1 = (double) Convert.ChangeType(intValue1, typeof(Double), null);
      Console.WriteLine("{0} ({1})--> {2} ({3})", intValue1, intValue1.GetType().Name,
                        dValue1, dValue1.GetType().Name);

      float fValue1 = 16.3478f;
      int? intValue2 = (int) fValue1;
      Console.WriteLine("{0} ({1})--> {2} ({3})", fValue1, fValue1.GetType().Name,
                        intValue2, intValue2.GetType().Name);
   }
}
// The example displays the following output:
//    12893 (Int32)--> 12893 (Double)
//    16.3478 (Single)--> 16 (Int32)
open System

let intValue1 = Nullable 12893
let dValue1 = Convert.ChangeType(intValue1, typeof<Double>, null) :?> double
printfn $"{intValue1} ({intValue1.GetType().Name})--> {dValue1} ({dValue1.GetType().Name})"

let fValue1 = 16.3478f
let intValue2 = Nullable(int fValue1)
printfn $"{fValue1} ({fValue1.GetType().Name})--> {intValue2} ({intValue2.GetType().Name})"

// The example displays the following output:
//    12893 (Int32)--> 12893 (Double)
//    16.3478 (Single)--> 16 (Int32)
Module Example
   Public Sub Main()
      Dim intValue1 As Integer? = 12893
      Dim dValue1 As Double = CType(Convert.ChangeType(intValue1, GetType(Double), Nothing), Double)
      Console.WriteLine("{0} ({1})--> {2} ({3})", intValue1, intValue1.GetType().Name,
                        dValue1, dValue1.GetType().Name)
      

      Dim fValue1 As Single = 16.3478
      Dim intValue2 As Integer? = CType(fValue1, Integer) 
      Console.WriteLine("{0} ({1})--> {2} ({3})", fValue1, fValue1.GetType().Name,
                        intValue2, intValue2.GetType().Name)
   End Sub
End Module
' The example displays the following output:
'       12893 (Int32)--> 12893 (Double)
'       16.3478 (Single)--> 16 (Int32)

Применяется к

ChangeType(Object, TypeCode, IFormatProvider)

Исходный код:
Convert.cs
Исходный код:
Convert.cs
Исходный код:
Convert.cs

Возвращает объект указанного типа, значение которого эквивалентно указанному объекту. Параметр предоставляет сведения о форматировании, зависящие от языка и региональных параметров.

public:
 static System::Object ^ ChangeType(System::Object ^ value, TypeCode typeCode, IFormatProvider ^ provider);
public static object ChangeType (object value, TypeCode typeCode, IFormatProvider provider);
public static object? ChangeType (object? value, TypeCode typeCode, IFormatProvider? provider);
static member ChangeType : obj * TypeCode * IFormatProvider -> obj
Public Shared Function ChangeType (value As Object, typeCode As TypeCode, provider As IFormatProvider) As Object

Параметры

value
Object

Объект, реализующий интерфейс IConvertible.

typeCode
TypeCode

Тип возвращаемого объекта.

provider
IFormatProvider

Объект, предоставляющий сведения о форматировании, зависящее от языка и региональных параметров.

Возвращаемое значение

Объект, базовый тип которого typeCode и значение которого эквивалентно value.

-или-

Пустая ссылка (Nothing в Visual Basic), если valuenull и typeCodeEmpty, Stringили Object.

Исключения

Это преобразование не поддерживается.

-или-

value null и typeCode указывает тип значения.

-или-

value не реализует интерфейс IConvertible.

value не имеет формата для типа typeCode, распознаваемого provider.

value представляет число, которое выходит за пределы диапазона типа typeCode.

typeCode недопустимо.

Примеры

В следующем примере определяется настраиваемый поставщик формата с именем InterceptProvider, указывающий, когда вызывается метод GetFormat и возвращает NumberFormatInfo для языка и региональных параметров fr-FR и объекта DateTimeFormatInfo для языка и региональных параметров en-US. Этот поставщик формата используется во всех вызовах метода ChangeType(Object, TypeCode, IFormatProvider). Затем в примере создается массив с Double и значением DateTime и выполняет повторяющиеся вызовы к ChangeType(Object, TypeCode, IFormatProvider) с каждым значением и каждым элементом перечисления TypeCode. В примере показано, когда метод использует параметр IFormatProvider, а также иллюстрирует использование параметра provider для выполнения форматирования с учетом языка и региональных параметров.

using namespace System;
using namespace System::Globalization;

ref class InterceptProvider : IFormatProvider
{
public: 
   virtual Object^ GetFormat(Type^ formatType) 
   {
      CultureInfo^ culture;
      if (formatType == NumberFormatInfo::typeid) {
         Console::WriteLine("   Returning a fr-FR numeric format provider.");
         
         culture = gcnew CultureInfo("fr-FR");
         return culture->NumberFormat;
      }  
      else if (formatType == DateTimeFormatInfo::typeid) {
         Console::WriteLine("   Returning an en-US date/time format provider.");
         culture = gcnew CultureInfo("en-US");
         return culture->DateTimeFormat;
      }
      else {
         Console::WriteLine("   Requesting a format provider of {0}.", formatType->Name);
         return nullptr;
      }
   }
};

void main()
{
   array<Object^>^ values = gcnew array<Object^> { 103.5, gcnew DateTime(2010, 12, 26, 14, 34, 0) };
   IFormatProvider^ provider = gcnew InterceptProvider();
      
   // Convert value to each of the types represented in TypeCode enum.
   for each (Object^ value in values)
   {
      // Iterate types in TypeCode enum.
      for each (TypeCode enumType in (array<TypeCode>^) Enum::GetValues(TypeCode::typeid))
      {         
         if (enumType == TypeCode::DBNull || enumType == TypeCode::Empty) continue;
            
         try {
            Console::WriteLine("{0} ({1}) --> {2} ({3}).", 
                              value, value->GetType()->Name,
                              Convert::ChangeType(value, enumType, provider),
                              enumType.ToString());
         }
         catch (InvalidCastException^ e) {
            Console::WriteLine("Cannot convert a {0} to a {1}",
                              value->GetType()->Name, enumType.ToString());
         }                     
         catch (OverflowException^ e) {
            Console::WriteLine("Overflow: {0} is out of the range of a {1}",
                              value, enumType.ToString());
         }
      }
      Console::WriteLine();
   }
}
// The example displays the following output:
//    103.5 (Double) --> 103.5 (Object).
//    103.5 (Double) --> True (Boolean).
//    Cannot convert a Double to a Char
//    103.5 (Double) --> 104 (SByte).
//    103.5 (Double) --> 104 (Byte).
//    103.5 (Double) --> 104 (Int16).
//    103.5 (Double) --> 104 (UInt16).
//    103.5 (Double) --> 104 (Int32).
//    103.5 (Double) --> 104 (UInt32).
//    103.5 (Double) --> 104 (Int64).
//    103.5 (Double) --> 104 (UInt64).
//    103.5 (Double) --> 103.5 (Single).
//    103.5 (Double) --> 103.5 (Double).
//    103.5 (Double) --> 103.5 (Decimal).
//    Cannot convert a Double to a DateTime
//       Returning a fr-FR numeric format provider.
//    103.5 (Double) --> 103,5 (String).
//    
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (Object).
//    Cannot convert a DateTime to a Boolean
//    Cannot convert a DateTime to a Char
//    Cannot convert a DateTime to a SByte
//    Cannot convert a DateTime to a Byte
//    Cannot convert a DateTime to a Int16
//    Cannot convert a DateTime to a UInt16
//    Cannot convert a DateTime to a Int32
//    Cannot convert a DateTime to a UInt32
//    Cannot convert a DateTime to a Int64
//    Cannot convert a DateTime to a UInt64
//    Cannot convert a DateTime to a Single
//    Cannot convert a DateTime to a Double
//    Cannot convert a DateTime to a Decimal
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (DateTime).
//       Returning an en-US date/time format provider.
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (String).
using System;
using System.Globalization;

public class InterceptProvider : IFormatProvider
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(NumberFormatInfo)) {
         Console.WriteLine("   Returning a fr-FR numeric format provider.");
         return new System.Globalization.CultureInfo("fr-FR").NumberFormat;
      }
      else if (formatType == typeof(DateTimeFormatInfo)) {
         Console.WriteLine("   Returning an en-US date/time format provider.");
         return new System.Globalization.CultureInfo("en-US").DateTimeFormat;
      }
      else {
         Console.WriteLine("   Requesting a format provider of {0}.", formatType.Name);
         return null;
      }
   }
}

public class Example
{
   public static void Main()
   {
      object[] values = { 103.5d, new DateTime(2010, 12, 26, 14, 34, 0) };
      IFormatProvider provider = new InterceptProvider();

      // Convert value to each of the types represented in TypeCode enum.
      foreach (object value in values)
      {
         // Iterate types in TypeCode enum.
         foreach (TypeCode enumType in ((TypeCode[]) Enum.GetValues(typeof(TypeCode))))
         {
            if (enumType == TypeCode.DBNull || enumType == TypeCode.Empty) continue;

            try {
               Console.WriteLine("{0} ({1}) --> {2} ({3}).",
                                 value, value.GetType().Name,
                                 Convert.ChangeType(value, enumType, provider),
                                 enumType.ToString());
            }
            catch (InvalidCastException) {
               Console.WriteLine("Cannot convert a {0} to a {1}",
                                 value.GetType().Name, enumType.ToString());
            }
            catch (OverflowException) {
               Console.WriteLine("Overflow: {0} is out of the range of a {1}",
                                 value, enumType.ToString());
            }
         }
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//    103.5 (Double) --> 103.5 (Object).
//    103.5 (Double) --> True (Boolean).
//    Cannot convert a Double to a Char
//    103.5 (Double) --> 104 (SByte).
//    103.5 (Double) --> 104 (Byte).
//    103.5 (Double) --> 104 (Int16).
//    103.5 (Double) --> 104 (UInt16).
//    103.5 (Double) --> 104 (Int32).
//    103.5 (Double) --> 104 (UInt32).
//    103.5 (Double) --> 104 (Int64).
//    103.5 (Double) --> 104 (UInt64).
//    103.5 (Double) --> 103.5 (Single).
//    103.5 (Double) --> 103.5 (Double).
//    103.5 (Double) --> 103.5 (Decimal).
//    Cannot convert a Double to a DateTime
//       Returning a fr-FR numeric format provider.
//    103.5 (Double) --> 103,5 (String).
//
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (Object).
//    Cannot convert a DateTime to a Boolean
//    Cannot convert a DateTime to a Char
//    Cannot convert a DateTime to a SByte
//    Cannot convert a DateTime to a Byte
//    Cannot convert a DateTime to a Int16
//    Cannot convert a DateTime to a UInt16
//    Cannot convert a DateTime to a Int32
//    Cannot convert a DateTime to a UInt32
//    Cannot convert a DateTime to a Int64
//    Cannot convert a DateTime to a UInt64
//    Cannot convert a DateTime to a Single
//    Cannot convert a DateTime to a Double
//    Cannot convert a DateTime to a Decimal
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (DateTime).
//       Returning an en-US date/time format provider.
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (String).
open System
open System.Globalization

type InterceptProvider() =
    interface IFormatProvider with
        member _.GetFormat(formatType: Type) =
            if formatType = typeof<NumberFormatInfo> then
                printfn "   Returning a fr-FR numeric format provider."
                CultureInfo("fr-FR").NumberFormat
            elif formatType = typeof<DateTimeFormatInfo> then
                printfn "   Returning an en-US date/time format provider."
                CultureInfo("en-US").DateTimeFormat
            else
                printfn $"   Requesting a format provider of {formatType.Name}."
                null

let values: obj[] = [| 103.5; DateTime(2010, 12, 26, 14, 34, 0)|]
let provider = InterceptProvider()

// Convert value to each of the types represented in TypeCode enum.
for value in values do
    // Iterate types in TypeCode enum.
    for enumType in Enum.GetValues typeof<TypeCode> :?> TypeCode[] do
        match enumType with
        | TypeCode.DBNull | TypeCode.Empty -> ()
        | _ ->
            try
                printfn $"{value} ({value.GetType().Name}) --> {Convert.ChangeType(value, enumType, provider)} ({enumType})."
            with
            | :? InvalidCastException ->
                printfn $"Cannot convert a {value.GetType().Name} to a {enumType}"
            | :? OverflowException ->
                printfn $"Overflow: {value} is out of the range of a {enumType}"
    printfn ""

// The example displays the following output:
//    103.5 (Double) --> 103.5 (Object).
//    103.5 (Double) --> True (Boolean).
//    Cannot convert a Double to a Char
//    103.5 (Double) --> 104 (SByte).
//    103.5 (Double) --> 104 (Byte).
//    103.5 (Double) --> 104 (Int16).
//    103.5 (Double) --> 104 (UInt16).
//    103.5 (Double) --> 104 (Int32).
//    103.5 (Double) --> 104 (UInt32).
//    103.5 (Double) --> 104 (Int64).
//    103.5 (Double) --> 104 (UInt64).
//    103.5 (Double) --> 103.5 (Single).
//    103.5 (Double) --> 103.5 (Double).
//    103.5 (Double) --> 103.5 (Decimal).
//    Cannot convert a Double to a DateTime
//       Returning a fr-FR numeric format provider.
//    103.5 (Double) --> 103,5 (String).
//
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (Object).
//    Cannot convert a DateTime to a Boolean
//    Cannot convert a DateTime to a Char
//    Cannot convert a DateTime to a SByte
//    Cannot convert a DateTime to a Byte
//    Cannot convert a DateTime to a Int16
//    Cannot convert a DateTime to a UInt16
//    Cannot convert a DateTime to a Int32
//    Cannot convert a DateTime to a UInt32
//    Cannot convert a DateTime to a Int64
//    Cannot convert a DateTime to a UInt64
//    Cannot convert a DateTime to a Single
//    Cannot convert a DateTime to a Double
//    Cannot convert a DateTime to a Decimal
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (DateTime).
//       Returning an en-US date/time format provider.
//    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (String).
Imports System.Globalization

Public Class InterceptProvider : Implements IFormatProvider
   Public Function GetFormat(formatType As Type) As Object _
          Implements IFormatProvider.GetFormat
      If formatType.Equals(GetType(NumberFormatInfo)) Then
         Console.WriteLine("   Returning a fr-FR numeric format provider.")
         Return New CultureInfo("fr-FR").NumberFormat
      ElseIf formatType.Equals(GetType(DateTimeFormatInfo)) Then
         Console.WriteLine("   Returning an en-US date/time format provider.")
         Return New CultureInfo("en-US").DateTimeFormat
      Else
         Console.WriteLine("   Requesting a format provider of {0}.", formatType.Name)
         Return Nothing
      End If
   End Function
End Class

Module Example
   Public Sub Main()
      Dim values() As Object = { 103.5r, #12/26/2010 2:34PM# }
      Dim provider As New InterceptProvider()
      
      ' Convert value to each of the types represented in TypeCode enum.
      For Each value As Object In values
         ' Iterate types in TypeCode enum.
         For Each enumType As TypeCode In DirectCast([Enum].GetValues(GetType(TypeCode)), TypeCode())         
            If enumType = TypeCode.DbNull Or enumType = TypeCode.Empty Then Continue For
            
            Try
               Console.WriteLine("{0} ({1}) --> {2} ({3}).", _
                                 value, value.GetType().Name, _
                                 Convert.ChangeType(value, enumType, provider), _
                                 enumType.ToString())
            Catch e As InvalidCastException
               Console.WriteLine("Cannot convert a {0} to a {1}", _
                                 value.GetType().Name, enumType.ToString())
            Catch e As OverflowException
               Console.WriteLine("Overflow: {0} is out of the range of a {1}", _
                                 value, enumType.ToString())
            End Try
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'    103.5 (Double) --> 103.5 (Object).
'    103.5 (Double) --> True (Boolean).
'    Cannot convert a Double to a Char
'    103.5 (Double) --> 104 (SByte).
'    103.5 (Double) --> 104 (Byte).
'    103.5 (Double) --> 104 (Int16).
'    103.5 (Double) --> 104 (UInt16).
'    103.5 (Double) --> 104 (Int32).
'    103.5 (Double) --> 104 (UInt32).
'    103.5 (Double) --> 104 (Int64).
'    103.5 (Double) --> 104 (UInt64).
'    103.5 (Double) --> 103.5 (Single).
'    103.5 (Double) --> 103.5 (Double).
'    103.5 (Double) --> 103.5 (Decimal).
'    Cannot convert a Double to a DateTime
'       Returning a fr-FR numeric format provider.
'    103.5 (Double) --> 103,5 (String).
'    
'    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (Object).
'    Cannot convert a DateTime to a Boolean
'    Cannot convert a DateTime to a Char
'    Cannot convert a DateTime to a SByte
'    Cannot convert a DateTime to a Byte
'    Cannot convert a DateTime to a Int16
'    Cannot convert a DateTime to a UInt16
'    Cannot convert a DateTime to a Int32
'    Cannot convert a DateTime to a UInt32
'    Cannot convert a DateTime to a Int64
'    Cannot convert a DateTime to a UInt64
'    Cannot convert a DateTime to a Single
'    Cannot convert a DateTime to a Double
'    Cannot convert a DateTime to a Decimal
'    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (DateTime).
'       Returning an en-US date/time format provider.
'    12/26/2010 2:34:00 PM (DateTime) --> 12/26/2010 2:34:00 PM (String).

Комментарии

ChangeType(Object, TypeCode, IFormatProvider) — это метод преобразования общего назначения, который преобразует объект, указанный value в предопределенный тип, указанный typeCode. Параметр value может быть объектом любого типа. Для успешного преобразования value необходимо реализовать интерфейс IConvertible, так как метод просто упаковывает вызов к соответствующему методу IConvertible. Этот метод также требует поддержки преобразования value в typeCode.

Метод ChangeType(Object, TypeCode, IFormatProvider) не поддерживает преобразование value в пользовательский тип. Чтобы выполнить такое преобразование, вызовите метод ChangeType(Object, Type, IFormatProvider).

Параметр provider — это реализация IFormatProvider, которая предоставляет сведения о форматировании для преобразования. Зависит ли этот параметр от базовой реализации IConvertible. Если value является базовым типом данных, provider используется только для следующих преобразований. Если аргумент nullIFormatProvider передается этим методам, используется объект CultureInfo, представляющий текущий язык и региональные параметры.

  • Преобразование из числа в строку или из строки в число. provider должен быть объектом CultureInfo, объектом NumberFormatInfo или пользовательской реализацией IFormatProvider, возвращающей объект NumberFormatInfo. Однако, поскольку метод ChangeType(Object, TypeCode, IFormatProvider) выполняет преобразование с помощью описателя формата G по умолчанию, параметр provider не действует, если value или целевой тип является целым числом без знака.

  • Преобразование из значения DateTime в строку или из строки в значение DateTime. provider должен быть объектом CultureInfo или DateTimeFormatInfo.

Если value является определяемым приложением типом, его реализация IConvertible может использовать параметр provider.

Применяется к