2009-05-20 8 views
4

Ce post va à une lacune dans ma compréhension des classes C# et pourquoi elles sont préférables aux fonctions statiques. J'essaie d'obtenir une liste d'objets. Chaque objet de la liste représente un enregistrement dans une table. Ce serait facile à faire dans une fonction statique.Ne pas comprendre l'instanciation de l'objet en C#

Utilisation d'une classe, que je suis capable de le faire comme suit:

appel de routine:

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

Les classes:

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

je ne pourrais pas réécrire la classe de sorte que cela pourrait être fait avec une ligne:

ListOfBusinesses l = new ListOfBusinesses(); 

Il me semble que la classe ListofBusinesses ci-dessus n'est qu'une fonction statique enveloppée dans une classe qui n'a pas de propriétés et qui n'est là que pour avoir une classe.

J'ai essayé:

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

Mais reçu l'erreur du compilateur « noms de membres ne peut pas être le même que le type y enfermant ». Par exemple, j'ai essayé d'utiliser un constructeur, mais il me manque quelque chose.

Toute aide pourrait m'éclairer dans un domaine que j'ai mal compris depuis un certain temps.

Mike Thomas

Répondre

1

Vous êtes à la recherche d'une méthode de fabrication au lieu d'un constructeur.

5

Bien sûr. Au lieu d'encapsuler List<Business>, étendez-le. Ensuite, il suffit d'ajouter des choses dans le constructeur.

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

Pour l'utiliser:

List<Business> l = new ListOfBusinesses(); 
+1

Pourquoi voudriez-vous étendre la classe générique List ? Je ne vois rien dans le code qui exige cela du tout. –

+0

Il semblait que Mike voulait une classe qui lui donnait une liste avec un ensemble de valeurs par défaut déjà ajouté. Il existe deux solutions: utiliser une fabrique ou étendre la liste par défaut. J'ai l'impression qu'il veut faire plus que d'ajouter quelques valeurs par défaut - peut-être ajouter quelques méthodes ou quelque chose - ce qui explique pourquoi il l'a encapsulé en premier lieu. Je pense juste que ce serait plus facile de l'étendre. –

1

Votre erreur de compilation est parce que votre nom de classe est « ListOfBusinesses » et le nom de la méthode est « ListOfBusinesses ». Ce serait bien si c'était un constructeur, mais puisque vous avez un type de retour, C# pense que vous vouliez que ce soit une méthode plutôt qu'un constructeur.

En ce qui concerne l'obtention de votre liste des entreprises, pourquoi ne pas créer une classe comme ceci:

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

ensuite l'utiliser:

BusinessService service = new BusinessService(); 
List<Business> businesses = service.GetBusinesses(); 
0

Le problème est que vous utilisez un mot réservé (new) utilisé pour invoquer le constructeur de la classe. La sémantique du constructeur est de renvoyer une instance de la classe qui est créée et elle suit la règle de ne pas avoir de valeur de retour et avoir le même nom de la classe.

Si ce n'était pas ainsi, si vous faites new MyObject ...Comment voulez-vous (ou le compilateur d'ailleurs) être censé connaître le type de retour?

1

Vous essayez de retourner quelque chose de différent de la classe dans le constructeur

public class ListOfBusinesses 
{ 
    ... 

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

Vous ne pouvez pas spécifier un type de retour dans un constructeur, vous avez besoin:

public ListOfBusinesses() 
{ 
    ... 

Comme Mike Thomas dit, vous devriez utiliser une usine à la place si c'est ce que vous voulez.

0

De manière générale, vous ne créez pas votre classe ListOfBusinesses, sauf si ListOfBusinesses possède des propriétés qui ne sont pas disponibles dans une liste <Business>. La façon la plus simple de la manipulation de c'est une méthode statique de la classe d'affaires, comme ceci:

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

Bien que ce soit de façon directe, le résultat final d'aller dans cette voie est de factoriser cette méthode de la classe affaires et dans une usine d'objets, communément fournie à travers un cadre ORM comme NHibernate ou Castle Windsor.

0

Comme les gens l'ont déjà dit - votre syntaxe n'est pas ici. ListOfBusiness() est un constructeur et ne renvoie pas explicitement un objet. Il fonctionne à la place sur une nouvelle instance de ListOfBusiness et devrait prendre soin de toute création nécessaire. Cela dit - si votre méthode pour créer le List<Business> est simple, il n'y a absolument aucune raison que cela fasse partie d'une méthode statique. Vous pouvez même définir une méthode d'extension sur List qui en prend une liste vide et la remplit. C'est ce qu'on appelle le modèle Factory, dans lequel une méthode ou une instance d'un objet prend en charge la création de nouvelles instances. Lorsque vous souhaitez étendre ListOfBusiness dans une classe instanciée, vous devez rechercher si des propriétés ou un état doivent être suivis. SI le List<Business> change chaque fois qu'il est appelé, ou si vous avez besoin d'un endroit pour ajouter de nouvelles entreprises, la classe ListOfBusiness peut être utile pour cela.

9

Je pense que vous mélangez les concepts d'une fonction statique, d'un constructeur et d'une méthode d'usine.

Fonction statique

Définition

C'est une méthode qui n'a pas accès (et n'est pas associée à) une this instance d'une classe.

Exemple

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

Utilisation

Appel d'une méthode statique avec le nom de la classe, pas une instance de la classe.

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

Constructor: Ceci est une méthode qui crée la this instance d'une classe. Il n'a pas de valeur de retour et est appelé lorsqu'un objet est instancié.

Exemple

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

Utilisation

Créer une nouvelle instance de l'objet.

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

Méthode usine

Définition

Ceci est une méthode qui crée une instance d'un objet, instancie en quelque sorte, et renvoie une référence.

Exemple

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

Utilisation

Appelez la méthode usine au lieu de créer un nouvel objet.

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

Deux choses à noter en outre:

  1. Vous déclarez un champ businesses, mais passez à une autre variable instancier appelé businesses dans votre méthode ListOfBusinesses() et le retourner. Rien n'arrivera au champ businesses. Soyez prudent avec la portée variable.

  2. Vous ne pouvez pas avoir un membre (champ, propriété ou méthode) portant le même nom que la classe. Ceci est réservé au constructeur, qui n'a pas de type de retour (voir ci-dessus). C'est pourquoi vous obtenez l'erreur du compilateur.

2

L'instanciation d'objet est fondamentalement la même pour tous les langages OO. L'utilisation de classes plutôt que de fonctions statiques permet une plus grande flexibilité et, en fin de compte, une réduction du codage, en particulier pour le suivi de nombreux éléments similaires.

Pensez aux livres et aux bibliothèques.

Si vous avez le livre en tant que classe d'objets, vous pouvez l'instancier pour créer beaucoup de livres et les stocker dans votre bibliothèque. Chaque livre que vous avez créé est unique. Si vous n'y avez pas apporté de modifications, chaque livre instancié semble être une copie de l'original (bien qu'à un niveau bas chaque livre ait un numéro de série unique). Il a la même couverture, le même nombre de pages et de contenu, MAIS vous pouvez facilement écrire votre nom en une copie, ce qui le rend différent du reste.

Si vous avez rendu le livre statique alors que vous ne pouvez pas créer de copies individuelles, vous regardez plutôt le même livre, mais à différents points de vue. Si vous écrivez votre nom, votre nom apparaît dans chaque vue du livre.

Je ne posterai aucun code car pendant que je tapais ce tas d'autres ont posté des exemples de code pour vos objets d'affaires.

0

Si je ne me trompe pas, vous voulez accéder à un db et récupérer une liste d'objets avec un appel de ligne unique. Tout d'abord, vous avez besoin d'une classe DAO qui encapsule l'accès db et expose une méthode List. A l'intérieur du DAO, vous pouvez utiliser NHibernate, Linq2XXX ou tout ce que vous voulez (échantillon)

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

votre code client pourrait simplement appeler

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

retourner un IQueryable au lieu d'une liste pourrait aider si vous êtes Linq activé .