c# - 使派生类能够仅实现选定数量的基类属性
问题描述
首先,我想描述一下我要解决的问题:
我想制作一个程序来处理法律民事案件。在每个法律案例中,都有一个List<IDocument> LegalDocuments
包含该法律案例中可能存在的任何和所有文档的对象。每个文档都派生自基本Document
类并实现IDocument
接口。可能的文档类型的数量是开放的,可以扩展到超过 100 种。在文档实现的基类中也有很少的公共属性,这是类:
public abstract class Document
{
//some general properties that all documents implement
//The expiration date of a document
public DateTime ExpirationDate { get; set; }
// The series of a document
public string DocSeries { get; set; }
//The serial number of a document
public int DocNumber { get; set; }
//the amount of money associated with the document
public decimal MoneyAmount { get; set; }
// signer of the document The exemplar of LegalSubject is presented below.
public LegalSubject Signer;
}
public class LegalSubject
{
//LegalSubject implementation
}
问题是:并非所有文档都具有所有呈现的属性。例子:
//passport: Has: ExpirationDate, DocSeries, DocNumber.
//Doesn't have: MoneyAmount, Signer
public class Passport : Document, ILegalDocument { }
//Payment Order: Has: DocNumber, MoneyAmount
// Doesn't have: The rest
public class PaymentOrder : Document, ILegalDocument { }
//Power of Attorney: Has: ExpirationDate, Signer
//Doesn't have: The rest
public class PowerOfAttorney : Document, ILegalDocument { }
// The common interface for the documents to fit into the list.
public interface ILegalDocument { }
这个想法是外部代码应该测试某个文档是否具有某个属性并根据结果启用/禁用相应的 UserForm 控件(例如)。
我能想到的唯一明智的方法是策略模式,其中我将每个属性的实现移动到一个单独的类并通过接口实现它们,这是代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace ExampleLegalDocuments
{
public class Passport : Document, ILegalDocument
{
public Passport()
{
//the constructor implements only the properties that Passports have.
ExpirationDate = new ExpirationDateEnabled();
Docseries = new DocSeriesEnabled();
DocNumber = new DocNumberEnabled();
}
}
//public class PaymentOrder : Document, ILegalDocument { }
//public class PowerOfAttorney : Document, ILegalDocument { }
//an interface for all derived types of documents
public interface ILegalDocument {
//The expiration date of a document
public IExpirationDate ExpirationDate { get; set; }
// serires of a document
public IDocSeries Docseries { get; set; }
// serial number of a document
public IDocNumber DocNumber { get; set; }
// a sum of money, associaned with the document
public IMoneyAmount MoneyAmount { get; set; }
// an exemplar of LegalSubject class (shown below) who is a signer of the document
public ISigner Signer { get; set; }
}
public abstract class Document
{
//some general properties that all documents implement
//The expiration date of a document
public IExpirationDate ExpirationDate { get; set; }
// serires of a document
public IDocSeries Docseries { get; set; }
// serial number of a document
public IDocNumber DocNumber { get; set; }
// a sum of money, associaned with the document
public IMoneyAmount MoneyAmount { get; set; }
// an exemplar of LegalSubject class (shown below) who is a signer of the document
public ISigner Signer { get; set; }
}
public class LegalSubject { }
//interfaces for the properties;
public interface IExpirationDate
{
public DateTime value { get; set; }
}
public interface IDocSeries
{
public string value { get; set; }
}
public interface IDocNumber
{
public string value { get; set; }
}
public interface IMoneyAmount
{
public decimal value { get; set; }
}
public interface ISigner
{
public LegalSubject value { get; set; }
}
//classes implementing the values through the interfaces shown above above
public class ExpirationDateEnabled : IExpirationDate
{
public DateTime value { get; set; }
}
public class DocSeriesEnabled : IDocSeries
{
public string value { get; set; }
}
public class DocNumberEnabled : IDocNumber
{
public string value { get; set; }
}
public class MoneyAmountEnabled : IMoneyAmount
{
public decimal value { get; set; }
}
public class SignerEnabled : ISigner
{
public LegalSubject value { get; set; }
}
}
执行:
using System;
using System.Collections.Generic;
namespace ExampleLegalDocuments
{
class Program
{
static void Main(string[] args)
{
Passport testPassport = new Passport();
if (testPassport.DocNumber is IDocNumber) { Console.WriteLine("property enabled"); }
else { Console.WriteLine("property not enabled"); }; //property enabled
if (testPassport.Signer is ISigner) { Console.WriteLine("property enabled"); }
else { Console.WriteLine("property not enabled"); }; //property not enabled
testPassport.DocNumber.value = "123";
List<ILegalDocument> LegalDocuments= new List<ILegalDocument>();
DocList.Add (testPassport);
Console.WriteLine("Document number is {0}", LegalDocuments[0].DocNumber.value); //Document number is 123
}
}
}
testPassport.Documenber.value
似乎对我有用,尽管我不喜欢更深入地访问一个值,即testPassport.value
我的方法是否正确?
解决方案
推荐阅读
- python - Python - 打印带有特殊字符的列表
- java - 从正在运行的线程之一结束无限循环(接受传入连接)
- windows - 在 windows 命令提示符中列出所有环境变量
- android - SimpleDateFormat("dd/MM/yy kk:mm") 将时间显示为 24:30 而不是 00:30
- ios - 在 xcode12.4 中找不到“CFSDK/CFSDK-Swift.h”文件
- javascript - 如何迭代多个http请求并解决一个promise直到循环结束?
- rust - 如何检查对象是否是 Rust 中的原始数据类型?
- python - 循环按顺序命名的变量
- blogger - 如何在博主html视图的桌面模式下选择文本?
- mysql - “[unixODBC][驱动程序管理器]无法打开 lib '/usr/lib/x86_84-linux-gnu/odbc/libmyodbc8w.so':找不到文件”