2009-05-20 3 views
4

Это сообщение относится к пробелу в моем понимании классов C# и почему они предпочтительнее статических функций.Непонимание объекта Objectiation in 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; 
    } 
} 

Но получил ошибку компилятора «имена членов не может быть такой же, как там ограждающих типа». Например, я попытался использовать конструктор, но я что-то упустил.

Любая помощь просветит меня в области, которую я неправильно понял в течение некоторого времени.

Mike Thomas

ответ

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(); 
+1

Зачем вам распространять общий список ? Я ничего не вижу в коде, который требует этого вообще. –

+0

Похоже, Майк хотел, чтобы класс дал ему список с уже установленным значением по умолчанию. Существует два решения: использовать фабрику или расширить список по умолчанию. У меня возникает ощущение, что он хочет сделать больше, чем добавить пару значений по умолчанию - возможно, добавить пару методов или что-то еще, и именно поэтому он инкапсулировал его в первую очередь. Я просто думаю, что было бы легче расширить его. –

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(); 
0

Проблема вы используете зарезервированное слово (new) используется для вызова конструктора класса.

Семантика конструктора должна возвращать экземпляр класса, который создается, и он следует правилу отсутствия возвращаемого значения и с тем же именем класса.

Если бы это было не так, то если у вас есть new MyObject ...как бы вы (или компилятор, если на то пошло) должны были знать возвращаемый тип?

1

Вы пытаетесь вернуть что-то другое, чем класс в конструкторе

public class ListOfBusinesses 
{ 
    ... 

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

Вы не можете указать тип возвращаемого значения в конструкторе, вам необходимо:

public ListOfBusinesses() 
{ 
    ... 

Как Майк Томас сказал, вместо этого вы должны использовать фабрику, если это то, что вы хотите.

0

Вообще говоря, вы бы не создали свой класс ListOfBusinesses, если только ListOfBusinesses не обладает некоторыми свойствами, которые недоступны в списке < Бизнес >. Самый простой способ обработки это статический метод на бизнес-класса, например, так:

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; 
    } 
} 

Хотя это простой способ, конечный результат того, чтобы идти по этому пути, чтобы реорганизовать этот метод из бизнес-класса и на объектную фабрику, обычно предоставляемую через инфраструктуру ORM, такую ​​как NHibernate или Castle Windsor.

0

Как уже говорили люди, ваш синтаксис здесь не прав. ListOfBusiness() - это конструктор и явно не возвращает объект. Вместо этого он работает с новым экземпляром ListOfBusiness и должен позаботиться о любом создании.

Это - если ваш метод создания List<Business> прост, нет абсолютно никакой причины, он должен быть частью статического метода. Вы даже можете определить метод расширения в List, который принимает пустой список этого и заполняет его. Это называется шаблоном Factory, в котором метод или экземпляр объекта берет на себя ответственность за создание новых экземпляров.

Если вы хотите подумать о расширении ListOfBusiness в экземпляр класса, это если есть свойства или состояние, которое необходимо отслеживать. ЕСЛИ List<Business> изменяется каждый раз, когда он вызывается, или если вам нужно место для добавления новых предприятий, для этого может оказаться полезным класс ListOfBusiness.

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(); 

Constructor: Это метод, который создает 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; 

Factory Method

Определение

Это метод, который создает экземпляр объекта, конкретизирует его в некотором роде, и возвращает ссылку на него.

Пример

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. У вас не может быть члена (поля, свойства или метода) с тем же именем, что и класс. Это зарезервировано для конструктора, который не имеет типа возврата (см. Выше). Вот почему вы получаете ошибку компилятора.

2

Объектная реализация в принципе одинакова для всех языков OO. Использование классов, а не статических функций обеспечивает гораздо большую гибкость и, в конечном счете, меньшее кодирование, особенно при отслеживании многих подобных элементов.

Подумайте о книгах и библиотеках.

Если у вас есть книга как класс объекта, вы можете создать экземпляр, чтобы создавать множество книг и хранить их в своей библиотеке. Каждая книга, которую вы создали, уникальна. Если вы не внесли никаких изменений, то каждая экземплярная книга представляется копией оригинала (хотя на низком уровне каждая книга имеет уникальный серийный номер). Он имеет одинаковую обложку, количество страниц и контента, но вы можете легко написать свое имя в одном экземпляре, что делает его другим для остальных.

Если вы сделали книгу статичной, хотя вы не можете создавать отдельные копии, вместо этого вы смотрите на ту же книгу, но с разных точек зрения. Если вы напишете свое имя в нем, ваше имя появится во всех представлениях книги.

Я не буду публиковать какой-либо код, пока я набирал это множество других, разместил образцы кода для ваших бизнес-объектов.

0

Если я не ошибаюсь, вы хотите получить доступ к базе данных и получить список объектов с помощью одного вызова.

Прежде всего вам нужен класс DAO, который инкапсулирует доступ к db и выставляет метод List. Внутри 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(); 

возвращающий IQueryable вместо списка может помочь, если вы позволили Linq ,

Смежные вопросы