bni*_*dyc 57 c# inheritance fluent-interface
我将通过示例展示一个问题.有一个具有流畅界面的基类:
class FluentPerson
{
private string _FirstName = String.Empty;
private string _LastName = String.Empty;
public FluentPerson WithFirstName(string firstName)
{
_FirstName = firstName;
return this;
}
public FluentPerson WithLastName(string lastName)
{
_LastName = lastName;
return this;
}
public override string ToString()
{
return String.Format("First name: {0} last name: {1}", _FirstName, _LastName);
}
}
Run Code Online (Sandbox Code Playgroud)
和一个儿童班:
class FluentCustomer : FluentPerson
{
private long _Id;
private string _AccountNumber = String.Empty;
public FluentCustomer WithAccountNumber(string accountNumber)
{
_AccountNumber = accountNumber;
return this;
}
public FluentCustomer WithId(long id)
{
_Id = id;
return this;
}
public override string ToString()
{
return base.ToString() + String.Format(" account number: {0} id: {1}", _AccountNumber, _Id);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,当你调用时,customer.WithAccountNumber("000").WithFirstName("John").WithLastName("Smith")
你无法添加.WithId(123)
到底,因为该WithLastName()
方法的返回类型是FluentPerson(不是FluentCustomer).
这个问题通常如何解决?
Ste*_*eck 44
尝试使用一些Extention方法.
static class FluentManager
{
public static T WithFirstName<T>(this T person, string firstName) where T : FluentPerson
{
person.FirstName = firstName;
return person;
}
public static T WithId<T>(this T customer, long id) where T : FluentCustomer
{
customer.ID = id;
return customer;
}
}
class FluentPerson
{
public string FirstName { private get; set; }
public string LastName { private get; set; }
public override string ToString()
{
return string.Format("First name: {0} last name: {1}", FirstName, LastName);
}
}
class FluentCustomer : FluentPerson
{
public long ID { private get; set; }
public long AccountNumber { private get; set; }
public override string ToString()
{
return base.ToString() + string.Format(" account number: {0} id: {1}", AccountNumber, ID);
}
}
Run Code Online (Sandbox Code Playgroud)
之后就可以使用了
new FluentCustomer().WithId(22).WithFirstName("dfd").WithId(32);
Run Code Online (Sandbox Code Playgroud)
Yan*_*vin 40
您可以使用泛型来实现这一点.
public class FluentPerson<T>
where T : FluentPerson<T>
{
public T WithFirstName(string firstName)
{
// ...
return (T)this;
}
public T WithLastName(string lastName)
{
// ...
return (T)this;
}
}
public class FluentCustomer : FluentPerson<FluentCustomer>
{
public FluentCustomer WithAccountNumber(string accountNumber)
{
// ...
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在:
var customer = new FluentCustomer()
.WithAccountNumber("123")
.WithFirstName("Abc")
.WithLastName("Def")
.ToString();
Run Code Online (Sandbox Code Playgroud)
一个需要流畅的接口、继承和一些泛型的解决方案......
无论如何,正如我之前所说:如果您想使用继承并访问受保护的成员,这是唯一的选择......
Run Code Online (Sandbox Code Playgroud)public class GridEx<TC, T> where TC : GridEx<TC, T> { public TC Build(T type) { return (TC) this; } } public class GridExEx : GridEx<GridExEx, int> { } class Program { static void Main(string[] args) { new GridExEx().Build(1); } }