不了解C#中的对象实例化

时间:2009-05-20 15:09:28

标签: c# instantiation

这篇文章对我对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;
    }
}

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

在我误解了一段时间的地方,任何帮助都会启发我。

迈克·托马斯

10 个答案:

答案 0 :(得分: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字段,但继续在businesses方法中实例化另一个名为ListOfBusinesses()变量并将其返回。 businesses字段不会发生任何事情。小心变量范围。

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

答案 1 :(得分: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();

答案 2 :(得分:2)

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

想想书籍和图书馆。

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分: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();

答案 5 :(得分:1)

你试图在构造函数

中返回与类不同的东西
public class ListOfBusinesses
{
    ...

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

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

public ListOfBusinesses()
{
    ...

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

答案 6 :(得分:0)

问题是你正在使用保留字(new)来调用类的构造函数

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

如果不是这样的话,那么,如果你做任何new MyObject ...你怎么会(或编译器)应该知道返回的类型?

答案 7 :(得分:0)

一般来说,除非ListOfBusinesses有一些List&lt; Business&gt;中没有的属性,否则不会创建ListOfBusinesses类。处理它的最简单方法是在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;
    }
}

虽然这是一种直截了当的方式,但沿着这条道路前进的最终结果是将此方法从Business类重构为对象工厂,通常通过像NHibernate或Castle Windsor这样的ORM框架提供。

答案 8 :(得分:0)

正如人们之前所说 - 你的语法不正确。 ListOfBusiness()是构造函数,不显式返回对象。它改为在ListOfBusiness的新实例上运行,并且应该处理任何必要的创建。

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

如果存在需要跟踪的属性或状态,那么您希望将ListOfBusiness扩展到实例化类中的位置。如果每次调用List<Business>时都会更改,或者如果您需要添加新业务的位置,则ListOfBusiness类可能对此有用。

答案 9 :(得分: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。