我最近发现了这样的代码:
public static implicit operator XElement(XmlBase xmlBase)
{
return xmlBase.Xml;
}
静态隐式运算符是什么意思?
我最近发现了这样的代码:
public static implicit operator XElement(XmlBase xmlBase)
{
return xmlBase.Xml;
}
静态隐式运算符是什么意思?
当前回答
我的意见。
这在单元测试将与构建器模式一起使用的不可变实体时非常有用。
假设您以不可变的方式定义了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
其他回答
另一个有趣的用法是(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 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;
我的意见。
这在单元测试将与构建器模式一起使用的不可变实体时非常有用。
假设您以不可变的方式定义了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