实现类似的类(数据实体对象)

时间:2012-04-20 15:16:44

标签: c# .net generics

我正在开发一个应用程序,该应用程序当前从sql查询的结果中创建数据实体对象。在数据库中,表格中的3个非常相似,但有几个不同的属性。

我最初的计划是创建3个不同的类,即使每个类非常相似。然而,当我开始创建返回对象列表的方法时,我遇到了绊脚石,因为返回类型将根据应用程序所处的模式而有所不同。

e.g。

public class A
{
   public int Id {get;}
   public string Name {get;}
}

 public class B
 {
   public int Id {get;}
   public string Name {get;}
   public string ExtraInfo {get;}
 }


 public class MainScreen
 {
     ...
     this.resultsGrid.DataSource = LoadData();
 }

我宁愿不写一种方法来加载每种数据类型的列表。 LoadData()的返回类型应该是什么,以使其尽可能通用。

处理这种情况的最优雅方式是什么?

谢谢,

肖恩

3 个答案:

答案 0 :(得分:0)

你应该有继承来允许多态,所以你会有一个基类,数据绑定中包含的所有实体都是从它派生的。

然后,您可以让中基类具有一些共享属性,如名称和ID。

基类:

public abstract class Entity
{
}

名称和ID的实体:

public class NameAndIDEntity : Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

具有名称,ID和ExtraInfo的实体:

public class NameIDAndExtraEntity : NameAndIDEntity
{
    public string ExtraInfo { get; set; }
}

具有其他信息的实体(不能从NameAndIDEntity派生),从实体派生,因此它可以包含在数据绑定中:

public class OtherInformationEntity : Entity
{
    public int Age { get; set; }
}

最后,您可以使LoadData返回类型为Entity。

答案 1 :(得分:0)

Simples!

创建一个类ListItem(我认为属性为IdName)。在工厂类/方法中,将该类的实例从记录中转换为List并将数据源绑定到列表。

不要害怕为您的UI创建专门的类。

更新:忘记提及。尽可能避免继承。

答案 2 :(得分:-1)

首先,您可以在项目中创建一个继承树,其中基类包含一组不同类型的共享/公共属性

其次,您可以从查询匿名类型中检索,然后通过将它们映射到真实类型将其映射到已知类型,例如来自Jon Skeet的博客Horrible grotty hack: returning an anonymous type instance

这意味着您需要知道哪个类型返回哪个查询(无法避免),但这可以减少您需要添加到代码中的分数,例如:

static class GrottyHacks
{
    internal static T Cast<T>(object target, T example) //CAST TO SPECIFIED TYPE
    {
        return (T) target;
    }
}

class CheesecakeFactory
{
    static object CreateCheesecake()
    {
        return new { Fruit="Strawberry", Topping="Chocolate" };
    }

    static void Main()
    {
        object weaklyTyped = CreateCheesecake(); //ANONYMOUS TYPE GENERATION
        var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
            new { Fruit="", Topping="" }); //"MAPPING"

        Console.WriteLine("Cheesecake: {0} ({1})",
            stronglyTyped.Fruit, stronglyTyped.Topping);            
    }
}