什么时候POCO类的扩展方法过度杀伤?

时间:2012-03-19 18:41:05

标签: c# linq extension-methods

我的POCO结构基本上是这样的:

Person具有:AddressesPhonesCaseNotesNoticeOfActions

我开始编写一个PersonExtension类,我发现这个类对以下示例方法非常有用:

public static Person GetPersonsPhones(this Person person, string userID)
{
    using (var context = ConnectDataContext.Create())
    {
        var pPhones =
            context.tblPhones.Where(phones => phones.PersonID == person.PersonID).Select(
                phones =>
                new Phone()
                    {
                        PhoneID = phones.PhoneID,
                        PhoneType =
                            new PhoneType
                                {
                                    PhoneTypeID = phones.tblAdminPhoneType.PhoneTypeID,
                                    TypeDescription = phones.tblAdminPhoneType.PhoneTypeDesc
                                },
                        PhoneNumber = phones.PhoneNumber,
                        Extension = phones.Extension
                    });
        person.Phones = pPhones.ToList<Phone>();
        return person;
    }
}

现在我有类似的获取地址集合的扩展方法。我想知道的是,如果有一点是有害的。由于我的环境的性质,几乎所有内容都以Person方式符合has-a

这样可以,还是有什么不好我会遇到的?我是否会以这种方式招致更多的开销?

另一种选择似乎是简单地传递Person.ID,因为这是我从数据库中获取电话所需要的,然后将其添加到我的Person对象中,但对我而言,无论如何,是一回事。


我认为这里存在通信故障,这很可能是我的错,因为我并不总是使用正确的词语。

在我的数据库中有tblPerson和tblPhone。我有一个名为Person的班级和一个名为Phone的班级。我的Person课程的属性为IList<Phone>Phones 有问题的扩展方法适用于我的基类的子属性的CRUD方法 即Person.GetPhones()填充该IList<Phone>Phones个对象的Person属性。 Person.SavePhones()Save PhonesPerson个对象的数据库LinqToSQL进行任何更改。

我并不是说我正在做的事情是正确的(我怀疑是...... :( )只是想确保每个人都理解我的要求。
另外,我使用{{1}}进行数据库访问。

4 个答案:

答案 0 :(得分:4)

你的人应该是一个完全成熟的domain object,而不是POCO。该人应tell some thing their phone numbers,该人不应负责前往数据库并将其取出!无论您选择是否使用扩展方法,后者都适用。

关于您的问题,我将扩展方法视为扩展第三方代码的某些功能的方法。例如,您可以对字符串执行ToUpper()。将此扩展为Title Case会很好。在这里,我们正在扩展行为。我们正在“添加”第三方代码而没有手头的源代码,因为替代方法是引入一个包装字符串的新对象来执行此操作。这里的扩展方法只是语法糖。

如果您拥有代码,那么扩展方法毫无意义,因为您可以将该方法设置为相关类的完全fledge方法。我之所以这么说是因为使用适当的方法可以访问正在扩展的类的私有字段,因此使用扩展方法只限于公共可见性,就像普通的静态方法一样。

答案 1 :(得分:3)

我认为主要的缺点往往是代码组织。尝试将相关代码保持在一起不是OOP的重点吗?

我很好奇为什么你在这里使用扩展方法。如果Person是一个实体对象,我会创建一个扩展实体类的分部类。对我来说似乎是一个更好的组织。

答案 2 :(得分:2)

如果您正在使用具有EntityFramework代码优先模型的POCO类,您应该能够像这样编写POCO类(现在只包括Phones,只是为了演示):

class Person 
{
    public long Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Phone> Phones { get; set; }
}

class Phone
{
    public long Id { get; set; }
    public string Name { get; set; }
    public long PersonId { get; set; }

    public virtual Person Person { get; set; }
}

现在,您可以直接访问myPerson.Phones,无需使用扩展程序。

答案 3 :(得分:0)

如果是你的班级,那么你应该为班级编写真正的方法。扩展方法对于向无法更改的类添加功能非常有用,例如,您没有源代码的库中的类以及您不能仅从中派生的类。