我有一个来自外部库的类对象,我想为它添加一些额外的属性。
让我们说外部课程是:
public class ExternalClass
{
public string EXproperty1 {get;set;}
public string EXproperty2 {get;set;}
public string EXproperty3 {get;set;}
public ExternalClass(){}
}
我有一个这些对象的列表,它被填充为
List<ExternalClass> listOfExternalClass=new List<ExternalClass>();
listOfExternalClass=GetListOfExternalClass();
我可以通过创建一个新类来扩展这个类,添加其他属性并使外部类成为属性。
public class NewClass
{
public ExternalClass ExternalClass {get;set;}
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
public NewClass(){}
public NewClass(ExternalClass externalClass){
this.ExternalClass=externalClass;
}
}
但是要将外部类的原始列表转换为新类的列表,我必须创建一个新的新类列表并遍历原始列表,创建一个新对象并将其添加到列表中,如< / p>
List<NewClass> listOfNewClass=new List<NewClass>();
foreach(var externalClass in listOfExternalClass)
{
listOfNewClass.Add(new NewClass(externalClass));
}
然后我就可以访问外部属性,如
listOfNewClass.FirstOrDefault().ExternalClass.EXproperty1;
我可以使用继承执行此操作还是使用更有效的方法?
理想情况下,我希望通过调用以下属性来结束:
listOfNewClass.FirstOrDefault().EXproperty1;
答案 0 :(得分:4)
如果你真的可以扩展易于完成的外部类:
public class NewClass: ExternalClass
{
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
public NewClass(){}
public NewClass(ExternalClass externalClass){
// you would have to copy all the properties
this.EXproperty1 = externalClass.EXproperty1;
}
}
答案 1 :(得分:4)
这当然可以通过继承来完成。请考虑以下事项。
//Inherit from our external class
public class NewClass: ExternalClass
{
//Note we do not have a copy of an ExternalClass object here.
//This class itself will now have all of its instance members.
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
//Base will call the constructor for the inherited class.
//If it has parameters include those parameters in NewClass() and add them to base().
//This is important so we don't have to write all the properties ourself.
//In some cases it's even impossible to write to those properties making this approach mandatory.
public NewClass(): base()
{
}
}
很少有人知道:
答案 2 :(得分:1)
是的继承是你正在寻找的:
<iframe width="420" height="315" [src]="'https://www.youtube.com/embed/' + v.videoCode"></iframe>
答案 3 :(得分:1)
如果您希望(或需要)代表团而不是副本,您可以这样做:
public class NewClass
{
public ExternalClass ExternalClass {get;set;}
public string NewProperty1 {get;set;}
public string NewProperty2 {get;set;}
public string EXproperty1 {get { return this.ExternalClass.EXproperty1; };set{ this.ExternalClass.EXproperty1 = value; }; }
public string EXproperty2 {get { return this.ExternalClass.EXproperty2; };set{ this.ExternalClass.EXproperty2 = value; }; }
public string EXproperty3 {get { return this.ExternalClass.EXproperty3; };set{ this.ExternalClass.EXproperty3 = value; }; }
public NewClass(){}
public NewClass(ExternalClass externalClass){
this.ExternalClass=externalClass;
}
}
答案 4 :(得分:0)
不是针对特定类型,而是针对接口。
下面我展示了facade pattern和adapter pattern的混合,将外部数据'转换'到明确定义的界面(IDocument
),有效地抽象出你正在处理的事情。< / p>
示例1:查询接口
以下是您要使用的类型:
public interface IDocument {
string Name { get; set; }
}
public interface IMetadata {
string[] Tags { get; set; }
}
如果您需要,这是您自己的代表:
public class RichDocument : IDocument, IMetadata {
public string Name { get; set; }
public string[] Tags { get; set; }
}
这是针对外部数据的包装器:
(门面和/或适配器概念的混蛋)
public class ExternalClass {
public string Whatever { get; set; }
}
public class ExternalDocument : IDocument /* only a basic object */ {
private readonly ExternalClass _class;
public ExternalDocument(ExternalClass @class) {
_class = @class;
}
public string Name {
get { return _class.Whatever; }
set { _class.Whatever = value; }
}
}
关于如何使用所有这些的演示:
internal class Demo1 {
public Demo1() {
var documents = new List<IDocument> {
new ExternalDocument(new ExternalClass()),
new RichDocument()
};
foreach (var document in documents){
var name = document.Name;
Console.WriteLine(name);
// see if it implements some interface and do something with it
var metadata = document as IMetadata;
if (metadata != null) {
Console.WriteLine(metadata.Tags);
}
}
}
}
示例2:有关组件的查询
通过推动概念以统一的方式处理所有内容,您可以在.NET框架,游戏开发或其他任何内容中找到它...
您将要解决的定义:
public interface IContainer {
IList<IComponent> Components { get; }
}
public interface IComponent {
// it can be/do anything
}
您将查询的一些组件:
public interface IDocument : IComponent {
string Name { get; set; }
}
public interface IMetadata : IComponent {
string[] Tags { get; set; }
}
您的“内部”类型:
public class Container : IContainer {
public Container() {
Components = new List<IComponent>();
}
public IList<IComponent> Components { get; }
}
针对外部数据的“包装”:
public class ExternalClass {
public string Whatever { get; set; }
}
public class ExternalContainer : IContainer {
private readonly List<IComponent> _components;
public ExternalContainer(ExternalClass @class) {
_components = new List<IComponent> {new ExternalDocument(@class)};
}
public IList<IComponent> Components {
get { return _components; }
}
}
public class ExternalDocument : IDocument {
private readonly ExternalClass _class;
public ExternalDocument(ExternalClass @class) {
_class = @class;
}
public string Name {
get { return _class.Whatever; }
set { _class.Whatever = value; }
}
}
一个用法示例:
public class Demo2 {
public Demo2() {
var containers = new List<IContainer> {
new ExternalContainer(new ExternalClass()),
new Container()
};
foreach (var container in containers) {
// query container for some components
var components = container.Components;
var document = components.OfType<IDocument>().FirstOrDefault();
if (document != null) {
Console.WriteLine(document.Name);
}
var metadata = components.OfType<IMetadata>().FirstOrDefault();
if (metadata != null) {
Console.WriteLine(metadata.Tags);
}
}
}
}
备注强>
继承的问题在于它是一种非常严格的方法,通常一旦你开始这样做,并且在某些时候你撞墙并想要恢复,很难摆脱它。
通过反对抽象,事物变得更加灵活,事物就会分离。
以下两个例子可能会促使您改变方法: