使用其他属性扩展类

时间:2017-02-24 12:58:33

标签: c# inheritance

我有一个来自外部库的类对象,我想为它添加一些额外的属性。

让我们说外部课程是:

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;

5 个答案:

答案 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()
    {

    }
}

很少有人知道:

  • 您的代码称为包装器。这是因为它&#34;包裹&#34;另一类或一组类。
  • 您不能从标记为已密封的类继承。
  • 在C#类中默认不密封。如果他们被密封,开发人员故意阻止您继承该课程。这通常是有充分理由的。

答案 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 patternadapter 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);
            }
        }
    }
}

备注

继承的问题在于它是一种非常严格的方法,通常一旦你开始这样做,并且在某些时候你撞墙并想要恢复,很难摆脱它。

通过反对抽象,事物变得更加灵活,事物就会分离。

以下两个例子可能会促使您改变方法:

Composition over inheritance

Using Components