Tam*_*yen 1 c# oop inheritance
假设我有一个类是
public class ClientModel
{
[Required]
public int Id { get; set; }
[Required]
[MinLength(2, ErrorMessage = "First name can not be shorter than 2 characters")]
public string FirstName { get; set; }
[Required]
[MinLength(2, ErrorMessage = "Last name can not be shorter than 2 characters")]
public string LastName { get; set; }
public string Email { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想将 ClientModel Obj 传递给函数,但没有电子邮件值。这样做的有效方法是什么(除了忽略函数中的电子邮件)。有没有办法当场创建一个新类减去我们不需要的字段?
OP 请通读XY 问题,我强烈怀疑您的问题有比您在这里要求的更好的解决方案。
实现这一点的一种方法是通过继承,但这实际上与您期望的相反,c# 中的子类型无法删除父类型中定义的成员的定义,因此在此解决方案中我们创建ClientModel子类型!
ClientModelBaseClientModel继承自的新类ClientModelBaseClientModelBase到ClientModel结果如下所示:
public class ClientModelBase
{
[Required]
public int Id { get; set; }
[Required]
[MinLength(2, ErrorMessage = "First name can not be shorter than 2 characters")]
public string FirstName { get; set; }
[Required]
[MinLength(2, ErrorMessage = "Last name can not be shorter than 2 characters")]
public string LastName { get; set; }
}
public class ClientModel : ClientModelBase
{
public string Email { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,在运行时,你可以投的实例为ClientModel到ClientModelBase,所以对于需要方法ClientModel 没有的Email属性,设置参数类型ClientModelBase。
// Get an instance of a client
ClientModel client = clientRepo.ByKey(123);
ProcessClientWithoutEmail(client);
...
public void ProcessClientWithoutEmail(ClientModelBase client)
{
// client doesn't expose an Email property
}
Run Code Online (Sandbox Code Playgroud)
这种隐式转换技术类似于C# 值装箱,如果您在逻辑链的后面需要它,电子邮件属性在技术上仍然可以访问,我们已经有效地将掩码应用于对象,以便编译器仅将其视为基本类型,当或者如果您需要,并且仅当原始实例是ClientModel您可以将引用转换回ClientModel确实具有该Email属性的引用。
除了为 ClientModel创建要继承的基类之外,您还可以使用interface. 然而,这需要更多的代码来实现,因为您需要完全定义接口的原型。最终结果是相似的,它对原始模型的影响较小,因为唯一的变化是声明 ClientMode实现了新IClientModelName接口:
public class ClientModel : IClientModelName
{
[Required]
public int Id { get; set; }
[Required]
[MinLength(2, ErrorMessage = "First name can not be shorter than 2 characters")]
public string FirstName { get; set; }
[Required]
[MinLength(2, ErrorMessage = "Last name can not be shorter than 2 characters")]
public string LastName { get; set; }
public string Email { get; set; }
}
public interface IClientModelName
{
int Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这几乎与前面的代码示例相同,但有一个重要区别,虽然仍然可以 Cast back to ClientModel,但我们现在可以传递与 ClientModel 来自的 repo 无关的对象,因此这简化了单元测试或嘲笑。
如果您的生产代码已经具有复杂的继承或其他影响初始化的因素,您可能会发现使用接口的基于组合的解决方案更适合您的用例。
// Get an instance of a client
ClientModel client = clientRepo.ByKey(123);
ProcessClientWithoutEmail(client);
...
public void ProcessClientWithoutEmail(IClientModelName client)
{
// client doesn't expose an Email property
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |