我最近发现了这样的代码:
public static implicit operator XElement(XmlBase xmlBase) { return xmlBase.Xml; }
static implicit operator是什么意思?
static implicit operator
这样一个隐式操作符意味着你可以隐式地将XmlBase转换为XElement。
XmlBase
XElement
XmlBase xmlBase = WhatEverGetTheXmlBase(); XElement xelement = xmlBase; //no explicit convert here like: XElement xelement = (XElement)xmlBase;
它是一个隐式转换操作符(与显式操作符相反,显式操作符需要(type)转换语法)
(type)
这是一个< >强转换操作符< / >强。这意味着你可以写这样的代码:
XmlBase myBase = new XmlBase(); XElement myElement = myBase;
编译器不会报错!在运行时,将执行转换运算符——将myBase作为参数传入,并返回有效的XElement作为结果。
myBase
这是你作为开发者告诉编译器的一种方式:
尽管这看起来像是两种完全不相关的类型,但实际上有一种方法可以将其中一种转换为另一种;让我来处理如何做这件事的逻辑。”
另一个有趣的用法是(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 } }
显然,最臭名昭著的使用可能是使用它将一个类转换为另一个类。但是将它们与基本类型一起使用也值得考虑……我很少看到有人提到它。
我的意见。
这在单元测试将与构建器模式一起使用的不可变实体时非常有用。
假设您以不可变的方式定义了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)); } }
这使得编写单元测试更容易,因为我们可以用所需的参数构造雇员。
例如,在第一个测试中,我们只关心名字和姓氏。对于第一种情况,我们不需要被年龄和街道所困扰。
第二种情况也是一样,我们只关心年龄。
文章引用。