我最近发现了这样的代码:

 public static implicit operator XElement(XmlBase xmlBase)
 {
     return xmlBase.Xml;
 }

静态隐式运算符是什么意思?


当前回答

这样一个隐式操作符意味着您可以隐式地将XmlBase转换为XElement。

XmlBase xmlBase = WhatEverGetTheXmlBase();
XElement xelement = xmlBase;   
//no explicit convert here like: XElement xelement = (XElement)xmlBase;

其他回答

我的意见。

这在单元测试将与构建器模式一起使用的不可变实体时非常有用。

假设您以不可变的方式定义了Employee域对象。当我们想要坚持DDD风格时,我们通常会这样做。

public class Employee 
{ 
  public Employee(int id, string firstname, string lastname, DateTime birthdate, string street) 
  { 
    this.ID = id; 
    this.FirstName = firstname; 
    this.LastName = lastname; 
    this.BirthDate = birthdate; 
    this.Street = street; 
  } 

  public int ID { get; private set; } 
  public string FirstName { get; private set; } 
  public string LastName { get; private set; }
  public DateTime BirthDate { get; private set; } 
  public string Street { get; private set; } 

  public string getFullName() 
  { 
    return this.FirstName + " " + this.LastName; 
  } 

  public int getAge() 
  { 
    DateTime today = DateTime.Today;
    int age = today.Year - BirthDate.Year;
    
    if (BirthDate > today.AddYears(-age))
      age--;

    return age; 
  } 
}

现在您可以拥有如下所示的雇员构建器(在测试项目内部)。注意到最后,我们有了这个隐式运算符。

public class EmployeeBuilder
{ 
  private int id = 1; 
  private string firstname = "first"; 
  private string lastname = "last"; 
  private DateTime birthdate = DateTime.Today; 
  private string street = "street"; 
  public Employee Build() 
  { 
    return new Employee(id, firstname, lastname, birthdate, street); 
  } 
  public EmployeeBuilder WithFirstName(string firstname) 
  { 
    this.firstname = firstname; 
    return this; 
  } 
  public EmployeeBuilder WithLastName(string lastname) 
  { 
    this.lastname = lastname; 
    return this; 
  } 
  public EmployeeBuilder WithBirthDate(DateTime birthdate) 
  { 
    this.birthdate = birthdate; 
    return this; 
  } 
  public EmployeeBuilder WithStreet(string street) 
  { 
    this.street = street; 
    return this; 
  } 
  public static implicit operator Employee(EmployeeBuilder instance) 
  { 
    return instance.Build(); 
  } 
}

现在您可以拥有如下所示的员工测试类。

public class EmployeeTest
{
  [Test]
  public void GetFullNameReturnsCombination()
  { 
    // Arrange
    Employee emp = new EmployeeBuilder().WithFirstName("Vivek").WithLastName("Koppula"); 
    // Act
    string fullname = emp.getFullName(); 
    // Assert
    Assert.That(fullname, Is.EqualTo("Vivek Koppula")); 
  } 

  [Test] 
  public void GetAgeReturnsCorrectValue() { 
  // Arrange
  Employee emp = new EmployeeBuilder().WithBirthDate(new DateTime(1983, 1,1)); 
  // Act
  int age = emp.getAge(); 
  // Assert
  Assert.That(age, Is.EqualTo(DateTime.Today.Year - 1983)); 
  } 
}

这使得编写单元测试更容易,因为我们可以用所需的参数构造雇员。

例如,在第一个测试中,我们只关心名字和姓氏。对于第一种情况,我们不需要被年龄和街道所困扰。

第二种情况也是一样,我们只关心年龄。

文章引用。

flexible-and-expressive-unit-tests-with-the-builder-pattern improve-tests-with-the-builder-pattern-for-test-data

这是一个转换运算符。这意味着你可以写这样的代码:

XmlBase myBase = new XmlBase();
XElement myElement = myBase;

编译器不会报错!在运行时,将执行转换操作符—将myBase作为参数传入,并返回一个有效的XElement作为结果。

这是你作为开发者告诉编译器的一种方式:

“尽管这看起来像是两种完全不相关的类型,但实际上有一种方法可以将其中一种转换为另一种;让我来处理怎么做的逻辑。”

另一个有趣的用法是(Unity检查对象(因此是MonoBehavior的实例)是否为空):

public static implicit operator bool (CustomClass c)
{
    return c != null;
}

注意,代码必须在类内部(在本例中为CustomClass)。这样你就可以这样做:

void Method ()
{
    CustomClass c1 = null;
    CustomClass c2 = new CustomClass ();

    bool b1 = c1; // is false
    bool b2 = c2; // is true

    if (!c1 && c2)
    {
        // Do stuff
    }
}

显然,最臭名昭著的使用可能是使用它将一个类转换为另一个类。但是将它们与基本类型一起使用也值得考虑……我很少看到有人提到它。

它是一个隐式转换操作符(与显式操作符相反,后者需要(类型)转换语法)

这样一个隐式操作符意味着您可以隐式地将XmlBase转换为XElement。

XmlBase xmlBase = WhatEverGetTheXmlBase();
XElement xelement = xmlBase;   
//no explicit convert here like: XElement xelement = (XElement)xmlBase;