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