SoFunction
Updated on 2025-03-07

In-depth understanding of explicit and implicit in C#

Preface

Today, I saw the following usage when I was studying the company's project framework.public static implicit operator JsonData(int data);. It seems that I haven't used this implicit conversion writing for a long time, so I revisited the conversion-related knowledge in C#.

explicit and implicit are conversion operators. If we use these two, we can support interchange of each other.

expliciti means explicit conversion, such as casting from A -> B (B = (B)A)

implicit means implicit conversion, such as from B -> A, you just need to directly assign values ​​(A = B)

implicit

The implicit keyword is used to declare implicit user-defined type conversion operators. If you can ensure that the conversion process does not cause data loss, you can use this keyword to implicitly convert between user-defined types and other types.

After using the implicit conversion operator, exception checks will be skipped at compile time, so the implicit conversion operator should never raise an exception and never lose information, otherwise some unexpected problems will arise at runtime.

Example

class Digit
{
 public Digit(double d) { val = d; }
 public double val;
 // ...other members

 // User-defined conversion from Digit to double
 public static implicit operator double(Digit d)
 {
  return ;
 }
 // User-defined conversion from double to Digit
 public static implicit operator Digit(double d)
 {
  return new Digit(d);
 }
}

class Program
{
 static void Main(string[] args)
 {
  Digit dig = new Digit(7);
  //This call invokes the implicit "double" operator
  double num = dig;
  //This call invokes the implicit "Digit" operator
  Digit dig2 = 12;
  ("num = {0} dig2 = {1}", num, );
  ();
 }
}

Implicit conversions can improve the readability of source code by eliminating unnecessary casts. However, because implicit conversion does not require programmers to explicitly cast one type to another, extra caution must be taken when using implicit conversion to avoid unexpected results. In general, implicit conversion operators should never throw exceptions and never lose information so that they can be used safely without the programmer's knowledge. If the conversion operator cannot satisfy those conditions, it should be marked as explicit. For more information, seeUse conversion operators

explicit display conversion

The explicit keyword declaration must be converted by calling the user-defined type conversion operator displayed.

The following example defines the operator that converts from the Fahrenheit class to the Celsius class. Operators must be defined in the Fahrenheit class or the Celsius class:

public static explicit operator Celsius(Fahrenheit fahr)
{
 return new Celsius((5.0f / 9.0f) * ( - 32));
}

As shown below, call the user-defined conversion operator to cast:

Fahrenheit fahr = new Fahrenheit(100.0f);
($"{} Fahrenheit");
Celsius c = (Celsius)fahr;

This conversion operator converts from the source type to the target type. The source type provides conversion operators. Unlike implicit conversions, explicit conversion operators must be called through conversion. If the conversion operation causes exceptions or loss of information, it should be marked as explicit. This prevents the compiler from silently calling conversion operations that may have unintended consequences.

Omitting the conversion will result in a compile-time error CS0266.

For more information, seeUse conversion operators

Example

The following example provides the Fahrenheit and Celsius classes, where each class provides an explicit conversion operator that converts to other classes.

class Celsius
{
 public Celsius(float temp)
 {
  Degrees = temp;
 }
 
 public float Degrees { get; }
 
 public static explicit operator Fahrenheit(Celsius c)
 {
  return new Fahrenheit((9.0f / 5.0f) *  + 32);
 }
}

class Fahrenheit
{
 public Fahrenheit(float temp)
 {
  Degrees = temp;
 }
 
 public float Degrees { get; }
 
 public static explicit operator Celsius(Fahrenheit fahr)
 {
  return new Celsius((5.0f / 9.0f) * ( - 32));
 }
}

class MainClass
{
 static void Main()
 {
  Fahrenheit fahr = new Fahrenheit(100.0f);
  ($"{} Fahrenheit");
  Celsius c = (Celsius)fahr;

  ($" = {} Celsius");
  Fahrenheit fahr2 = (Fahrenheit)c;
  ($" = {} Fahrenheit");
 }
}
// Output:// 100 Fahrenheit = 37.77778 Celsius = 100 Fahrenheit

Example

The following example defines the structure Digit, which represents a single decimal number. Defines the operator as a conversion from byte to Digit, but since not all bytes can be converted to Digit, the conversion should apply an explicit conversion.

struct Digit
{
 byte value;
 public Digit(byte value)
 {
  if (value > 9)
  {
   throw new ArgumentException();
  }
   = value;
 }

 // Define display conversion from byte to Digit explicit operator: public static explicit operator Digit(byte b)
 {
  Digit d = new Digit(b);
  ("Conversion completed");
  return d;
 }
}

class ExplicitTest
{
 static void Main()
 {
  try
  {
   byte b = 3;
   Digit d = (Digit)b; // Display conversion  }
  catch (Exception e)
  {
   ("{0} Capture 10%.", e);
  }
 }
}
/*
 Output:
 Conversion completed
 */

References

  • explicit
  • operator (C# Reference)
  • How to: Implement User-Defined Conversions Between Structs
  • implicit

Summarize

The above is the entire content of this article. I hope that the content of this article has certain reference value for your study or work. Thank you for your support.