5

这篇文章谈到了我对 C# 类的理解以及为什么它们比静态函数更可取的一个空白。

我正在尝试获取对象列表。列表中的每个对象代表表中的一条记录。这在静态函数中很容易做到。

使用一个类,我已经能够做到以下几点:

调用例程:

ListOfBusinesses l = new ListOfBusinesses ();
List<Business> b = l.listBusinesses();

课程:

 public class Business
 {
    public string Bupk { get; set; }
    public string Bu_name { get; set; }

 }  

 public class ListOfBusinesses
 {
    public List<Business> listBusinesses()
    {

      List<Business> businesses = new List<Business>();
      businesses.Add(new Business("1", "Business Name 1"));
      businesses.Add(new Business("2", "Business Name 2"));

      return businesses;
    }
 }

我不能重写这个类,这样就可以用一行来完成:

ListOfBusinesses l = new ListOfBusinesses();

在我看来,上面的 ListofBusinesses 类只不过是一个封装在一个没有属性的类中的静态函数,只是为了拥有一个类而存在。

我试过了:

public class ListOfBusinesses
{
    List<Business> businesses;

    public List<Business> ListOfBusinesses()
    {

      List<Business> businesses = new List<Business>();
      businesses.Add(new Business("1", "Business Name 1"));
      businesses.Add(new Business("2", "Business Name 2"));

      return businesses;
    }
}

但收到编译器错误“成员名称不能与封闭类型相同”。例如,我尝试使用构造函数,但缺少一些东西。

任何帮助都会在我误解了一段时间的领域启发我。

迈克·托马斯

4

10 回答 10

9

我认为您混淆了静态函数、构造函数和工厂方法的概念。

静态函数

定义

这是一种方法,它不能访问(并且不与)this类的实例。

例子

public class BusinessHelper
{   
    public static List<Business> ListBusinesses()
    {

        List<Business> businesses = new List<Business>();
        businesses.Add(new Business("1", "Business Name 1"));
        businesses.Add(new Business("2", "Business Name 2"));

        return businesses;
    }
}

用法

使用类名而不是类的实例调用静态方法。

List<Business> businesses = BusinessHelper.ListBusinesses();

构造函数:这是一个创建this类实例的方法。它没有返回值,并在实例化对象时调用。

例子

public class BusinessList
{   
    public List<Business> TheList;

    public BusinessList()
    {    
        TheList = new List<Business>();
        TheList.Add(new Business("1", "Business Name 1"));
        TheList.Add(new Business("2", "Business Name 2"));   
    }
}

用法

创建对象的新实例。

BusinessList myBusinessList = new BusinessList();
businesses = myBusinessList.TheList;

工厂方法

定义

这是一种创建对象实例、以某种方式实例化它并返回对它的引用的方法。

例子

public class BusinessList
{   
    public List<Business> TheList;

    public static BusinessList BusinessListWithTwoCompanies()
    {
        BusinessList instance = new BusinessList();

        businesses = new List<Business>();
        businesses.Add(new Business("1", "Business Name 1"));
        businesses.Add(new Business("2", "Business Name 2"));

        return instance;
    }
}

用法

调用工厂方法而不是创建新对象。

BusinessList myBusinessList = BusinessList.BusinessListWithTwoCompanies();
businesses = myBusinessList.TheList;

另外需要注意两点:

  1. 您声明一个businesses字段,但继续实例化在您的方法中调用的另一个变量并返回它。场上什么都不会发生。小心变量范围。businessesListOfBusinesses()businesses

  2. 您不能拥有与类同名的成员(字段、属性或方法)。这是为没有返回类型的构造函数保留的(见上文)。这就是您收到编译器错误的原因。

于 2009-05-20T15:28:53.533 回答
5

当然。与其封装List<Business>,不如扩展它。然后你只需要在构造函数中添加一些东西。

public class ListOfBusinesses : List<Business> {
    public ListOfBusinesses() : base() {
        Add(new Business("1", "Business Name 1"));
        Add(new Business("2", "Business Name 2"));
    }
}

要使用它:

List<Business> l = new ListOfBusinesses();
于 2009-05-20T15:16:09.050 回答
2

对于所有 OO 语言,对象实例化基本相同。使用类而不是静态函数可以提供更大的灵活性并最终减少编码,尤其是在跟踪许多类似项目时。

想想书籍和图书馆。

如果您将书籍作为对象类,那么您可以实例化它以创建大量书籍并将它们存储在您的图书馆中。您创建的每一本书都是独一无二的。如果您没有对其进行任何更改,那么每本实例化的书似乎都是原版的副本(尽管在低级别每本书都有一个唯一的序列号)。它具有相同的封面、页数和内容,但您可以轻松地将您的名字写在一份副本中,从而使其与其他副本不同。

如果您将这本书设为静态,那么虽然您不能创建单独的副本,但您正在查看同一本书,但从不同的角度来看。如果你在里面写下你的名字,那么你的名字就会出现在这本书的每个视图中。

我不会发布任何代码,因为当我一直在输入这些代码时,很多其他人已经为您的业务对象发布了代码示例。

于 2009-05-20T16:00:22.407 回答
1

您正在寻找工厂方法而不是构造函数。

于 2009-05-20T15:14:35.697 回答
1

您的编译器错误是因为您的类名是“ListOfBusinesses”,方法名也是“ListOfBusinesses”。如果它是一个构造函数,这会很好,但由于你有一个返回类型,C# 认为你的意思是它是一个方法而不是一个构造函数。

至于获取您的企业列表,为什么不创建一个这样的类:

public class BusinessService {
   public List<Business> GetBusinesses() {
       // Build and return your list of objects here.
   }
}

然后使用它:

BusinessService service = new BusinessService();
List<Business> businesses = service.GetBusinesses();
于 2009-05-20T15:16:19.610 回答
1

您试图返回与构造函数中的类不同的东西

public class ListOfBusinesses
{
    ...

    public List<Business> ListOfBusinesses()
    {
        ...

您不能在构造函数中指定返回类型,您需要:

public ListOfBusinesses()
{
    ...

正如迈克托马斯所说,如果你想要的话,你应该使用工厂。

于 2009-05-20T15:19:13.503 回答
0

问题是您使用了用于调用类的构造函数的保留字(新)。

构造函数的语义是返回正在创建的类的一个实例,它遵循没有返回值和类同名的规则。

如果不是这样,那么,如果你做任何事情new MyObject......你(或就此而言的编译器)应该如何知道返回类型?

于 2009-05-20T15:16:42.667 回答
0

一般来说,您不会创建 ListOfBusinesses 类,除非 ListOfBusinesses 具有 List<Business> 中不可用的某些属性。处理此问题的最简单方法是 Business 类上的静态方法,如下所示:

public class Business
{
    //Business class methods/properties/fields

    static List<Business> GetList()
    {
        List<Business> businesses = new List<Business>();
        businesses.Add(new Business("1", "Business Name 1"));
        businesses.Add(new Business("2", "Business Name 2"));
        return businesses;
    }
}

虽然这是直截了当的方法,但走这条路的最终结果是将此方法从业务类中重构到对象工厂中,通常通过像 NHibernate 或 Castle Windsor 这样的 ORM 框架提供。

于 2009-05-20T15:21:56.823 回答
0

正如人们之前所说 - 你的语法不在这里。ListOfBusiness()是一个构造函数并且不显式返回一个对象。相反,它对 的新实例进行操作,ListOfBusiness并且应该负责任何必要的创建。

也就是说 - 如果您创建的方法List<Business>很简单,那么绝对没有理由将它作为静态方法的一部分。您甚至可以在 List 上定义一个扩展方法,该方法接受一个空列表并填充它。这称为工厂模式,其中对象的方法或实例负责创建新实例。

您想要考虑扩展ListOfBusiness到实例化类的地方是是否有需要跟踪的属性或状态。如果List<Business>每次调用时都发生了变化,或者如果您需要一个地方来添加新的业务,那么ListOfBusiness该类可能对此很有用。

于 2009-05-20T15:24:17.380 回答
0

如果我没记错的话,您想访问数据库并通过单行调用检索对象列表。

首先,您需要一个封装了 db 访问并公开 List 方法的 DAO 类。在 DAO 中,您可以使用 NHibernate、Linq2XXX 或任何您想要的(示例)

public class BusinessItem
{
    public string Code { get; set; }
    public string Description { get; set; }
}

public class BusinessItemsDAO
{
...
    public List<BusinessItem>   List()
    {
        // fake... should retrieve from db
        var list = new List<BusinessItem>();

        // returs the list
        return list;
    }
...
}

您的客户端代码可以调用

var listOfBusinessItems = new BusinessItemsDAO().List();

如果您启用了 Linq,则返回 IQueryable 而不是 List 可能会有所帮助。

于 2009-05-20T16:25:23.607 回答