简体   繁体   English

在通用方法中处理类的特定属性

[英]Handling class specific properties in a generic method

I'm still wrapping my head around generics and have run up against a challenge that I want to work through correctly. 我仍在围绕仿制药而奋斗,遇到了我想正确应对的挑战。 If I have a few classes defined like so: 如果我有几个这样定义的类:

public abstract class DocBase {
    public long ID { get; set; }                                    
    public string Description { get; set; }             
    public long DocumentID { get; set; }                
    public string DocumentDate { get; set; }            
    ...snipped...
}

public class AppDoc : DocBase {
    public string A { get; set; }                                    
    public string B { get; set; }             
    public string C { get; set; }                    
}

public class OtherDoc : DocBase {
    public string D { get; set; }                                    
    public string E { get; set; }             
    public string F { get; set; }                    
}

I have a class that will be used to retrieve these documents 我有一个用于检索这些文档的类

public class Repo<T> where T : DocBase, new() 

This class will contain a method: 此类将包含一个方法:

public List<T> GetDocs()

In this method I want to be able to access the properties defined in the derived classes (so in AppDoc: A,B,C and in OtherDoc: D,E,F). 在这种方法中,我希望能够访问派生类中定义的属性(因此在AppDoc:A,B,C和OtherDoc:D,E,F中)。 But if I declare a new object like so: 但是,如果我这样声明一个新对象:

var doc = new T();

At design time I only have the properties available in the base class (DocBase) and not the dervied classes (AppDoc and OtherDoc). 在设计时,我只有基类(DocBase)中可用的属性,而派生类(AppDoc和OtherDoc)中没有可用的属性。 How do I get to properties A, B, C, D, E and F? 如何前往物业A,B,C,D,E和F?

EDIT: To elaborate on my "how do I get to..." a bit. 编辑:详细说明我的“我该如何去...”。 I need to populate properties A, B, C, D, E and F within the GetDocs() method from a list of results I get back from a database. 我需要从数据库返回的结果列表中填充GetDocs()方法中的属性A,B,C,D,E和F。

public List<T> GetDocs(){    

var results = someService.GetMyDocuments();
var documents = new List<T>();

    foreach(IRepositoryRow row in results) {
        var newDoc = new T();

        newDoc.A = row.GetProperty("AFromDatabase").ToString();
        newDoc.B = row.GetProperty("BFromDatabase").ToString();

        documents.Add(newDoc);    
    }

    return documents;
}

That's generally flawed. 这通常是有缺陷的。 Your design would break the laws of polymorphism entirely, because you want access to aa derived class' properties where only base class information is available. 您的设计将完全打破多态性的法则,因为您希望访问只有基类信息可用的派生类的属性。

So the question is not How can I ... but What's wrong with my design? 所以问题不是我怎么...而是我的设计出了什么问题? .

Edit : OR Mappers (eg Entity Framework or NHibernate) can handle such polymorphism scenarios automatically for you. 编辑 :或映射器(例如Entity Framework或NHibernate)可以为您自动处理这种多态情况。 I suggest you take this route. 我建议你走这条路。

It depends what are you wanting to do with those properties. 这取决于您要如何使用这些属性。

If you are manipulating them (eg populating them or calculating thigns based on them) then an abstract method on DocBase like DoStuff could then be called safely on your T and it could do whatever you want with the properties. 如果要操作它们(例如,填充它们或基于它们来计算DocBase ,则可以在T上安全地调用DocBase上的抽象方法(如DoStuff ,并且可以对属性进行任何操作。

If you want to do different things depending on what the object is then that's not really being very generic and you probably want to rethink things a bit, preferably to having abstract or virtual methods that you can call on the objects. 如果您想根据对象是什么来做不同的事情,那并不是很通用,您可能需要重新考虑一下事情,最好是拥有可以在对象上调用的抽象或虚拟方法。

Some sample code based on what you've put in your question: 一些基于您所提出的问题的示例代码:

public abstract class DocBase {
    ...
    public abstract void LoadProperties(IRepositoryRow row);
    ...
}

public List<T> GetDocs(){    

    var results = someService.GetMyDocuments();
    var documents = new List<T>();

    foreach(IRepositoryRow row in results) {
        var newDoc = new T();
        newDoc.LoadProperties(row);
        documents.Add(newDoc);    
    }
    return documents;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM