Domanda

Sono di fronte a un problema che non so come risolvere e sto sperando che la comunità può aiutare.

Sto scrivendo un app che gestisce gli oggetti "guidare". (Queste sono opportunità di vendita.) Una parte del mio programma consente di importare i contatti da un file di testo. Ora, il file di testo contiene un sacco di potenziali contatti, alcuni dei quali mi da importare e alcuni dei quali non lo farò.

Per la facilità di programmazione (e l'uso), sto analizzando il file di testo in un List oggetto, e utilizzando un DataGridView per visualizzare i contatti impostando la proprietà DataSource del DataGridView.

Quello che voglio fare è aggiungere una colonna alla griglia, chiamato "Importa", con una casella di controllo che l'utente può controllare per indicare se ciascun cavo deve essere importata.

Il mio primo pensiero è quello di derivare una classe da piombo:

public Class LeadWithImportCheckbox : Lead
{
   bool bImport = false;

public bool Import { get { return bImport;} set { bImport = value;} } }

Tuttavia, il motore di analisi restituisce un elenco di oggetti di piombo. Non posso downcast un Lead a un LeadWithImportCheckbox. Ciò non è riuscito:

LeadWithImportCheckbox newLead = (LeadWithImportCheckbox)LeadFromParsingEngine;
Si tratta di un cast valido.

L'altra opzione che vedo è quello di creare un costruttore per LeadWithImportCheckbox:

public LeadWithImportCheckbox(Lead newlead)
{
  base.Property1 = newlead.Property1;
  base.Property2 = newlead.Property2;
  ....
  base.Property_n = newlead.Property_n;
}
Questo è problematico per due ragioni. Uno, l'oggetto piombo ha diverse decine di proprietà e la scrittura di questo costruttore è una valle di lacrime.

Ma il peggio, se mai cambiare la struttura di base di piombo, ho bisogno di ricordare a tornare indietro e cambiare questo costruttore per LeadWithImportCheckbox. Questo è un pericolo per il mio manutenzione del codice.

C'è un modo migliore di realizzare il mio obiettivo?

È stato utile?

Soluzione

o, per evitare l'aspetto pita, l'uso di riflessione ... (provare questo ...)

EDIT: proprietà utilizzo, non campo come avevo inizialmente scritto ...

public class NewLead : Lead
{
    public bool Insert;
    public NewLead(Lead lead, bool insert)
    {
        Insert = insert;
        foreach (PropertyInfo pi in typeof(Lead).GetProperties())
            GetType().GetProperty(pi.Name).SetValue
               (this, pi.GetValue(lead,null), null);
    }
}

Altri suggerimenti

public class LeadListItem
{
    public Lead Lead { get; set; }
    public bool ShouldImport { get; set; }
}

vale a dire. non copiare il contenuto dell'oggetto piombo, basta memorizzare un riferimento ad esso in un nuovo oggetto LeadListItem, che aggiunge informazioni extra "al di fuori" l'oggetto originale.

Se si desidera che le proprietà del Piombo a comparire in rete, non v'è quasi certamente un modo di fare questo. Perché non chiedere che la questione, invece di downvoting per dirvi la risposta giusta a questa domanda!

Un paio di opzioni che potrebbe avere perso:

  • Si potrebbe aggiornare l'oggetto di piombo in sé ad avere una proprietà di importazione (valore predefinito false).
  • Si potrebbe avere l'oggetto "ImportLead" trattare in vantaggio con payload (anche renderla generica, se volete), quindi non è necessario il grande costruttore.
  • Crea un nuovo elenco di oggetti di piombo o enumerabile che solo contiene gli oggetti che si desidera importare in primo luogo.

È possibile abbattuta solo se l'oggetto ad essere abbattuto è davvero un oggetto di quel tipo.

Un modo più semplice per risolvere il problema sarebbe quello di avere una classe DisplayLead, come ad esempio:

  public class DisplayLead {
      Lead lead;
      bool bImport;
  }

che sarebbe anche aiutare a separare i dati memorizzati dal loro rappresentazione in una GUI.

Che cosa si vuole fare è visualizzare la colonna casella sulla griglia e non lo hanno correlato a tutti per i vostri oggetti di piombo. È possibile utilizzare le colonne contrassegnati (ed eventuale lista originale) per costruire una nuova serie di lista che sarà la vostra lista di importazione.

Poi gestire tutto ciò che si desidera fare con la lista appena creata.

Modifica: Una cosa da stare attenti quando si lavora con le liste è il fatto ogni oggetto classe è in realtà solo un puntatore alla classe, quindi se si lavora con l'elenco originale e fare qualcosa di simile:

List<Lead> Importable = new List<Lead>();

for(int i=0, i++, i<viewGrid.Count)
    if(viewGrid[i].CheckedColumn.Checked)
        Importable.Add(OriginalList[i]);

che esisteranno oggetti in entrambe le liste e se si modificano i dati di una pista su due liste sia sarà cambiato.

Non riesco a bassi a qualcosa che non è. Se l'oggetto è stato istanziato come Lead, allora non può essere abbattuto a qualsiasi classe derivata. Se fosse istanziato come un LeadWithImportCheckbox e poi tornò al codice come Lead, allora si può downcast esso.

Protip: Controllare tipo a runtime con operatore is

.

Ci sono molti modi per farlo, ma il modo "giusto" schiocca a causa di quello che hai detto, qui:

  

Per la facilità di programmazione (e l'uso), sono   l'analisi del file di testo in un   oggetto List, e utilizzando un   DataGridView per visualizzare i conduttori di   impostare la proprietà DataSource del   DataGridView.

     

Quello che voglio fare è aggiungere una colonna   la griglia, chiamato "Importa", con un   casella di controllo che l'utente può controllare   indicare se ogni cavo   dovrebbero essere importati.

Il vostro Lead sta bene da solo, e si desidera collegare alcuni metadati ad esso - non si vuole creare un'altra classificazione Lead (vale a dire la classe LeadWithImportCheckbox)

.

Quindi, l'approccio migliore nel tuo caso è quello di avere una classe in questo modo:

public class LeadInfo 
{
    private Lead lead;
    private bool shouldImport;

    public LeadInfo(Lead lead)
    {
        this.lead = lead;
        this.ShouldImport = false;
    }

    public bool ShouldImport 
    { 
        get { return shouldImport;  }
        set { shouldImport = value; }  
    }
}

Questa scala bene quando si desidera aggiungere altri metadati alla vostra lista, come se si desidera inviare promemoria via email te stesso su di loro ogni settimana.

Ho visto la soluzione corretta elencato tante volte mi sento come un tacco distacco di nuovo, ma il modo migliore per affrontare questo è quello di scrivere un wrapper per l'oggetto piombo che include il flag di importazione.

Se le proprietà dell'oggetto piombo non compaiono nella GridView, perché si sta associazione dati per l'oggetto, quindi scrivere le proprietà passthrough che rispecchiano le caratteristiche di piombo sul oggetto wrapper.

Il problema è che si desidera qualcosa mostrata all'utente che non è parte integrante del modello di dati. La risposta è quella di avvolgere i dati prima di presentarlo per l'utente in modo da poter controllare ciò che vedono senza cambiare il modello sottostante.

Se sei preoccupato che l'oggetto piombo cambierà così tante volte in futuro che cambia per l'involucro sarà ingombrante, si poteva guardare nella generazione di codice dinamico in base all'oggetto di piombo che genererà automaticamente un oggetto wrapper con la stessi campi come l'oggetto piombo più la bandiera di importazione. Anche se, francamente, che è molto più lavoro di quanto avrete probabilmente bisogno di qualcosa di così semplice come questo.

Come soluzione rapida e sporca, è possibile creare l'oggetto 'casella' come un oggetto diverso che contiene un'istanza di piombo.

public GridLead {
   public bool Import { get; set; }
   public Lead Lead { get; set; }
}

In questo modo si possono facilmente aggiungere più 'grid' oggetti da questo oggetto, pur sempre mantenendo un riferimento ai dettagli di piombo senza hardcoding clonazione di proprietà in esso.

consiglio di provare la modifica (upgrading) gli oggetti di piombo importati.

Prova a partire con gli esempi qui ...

Se la classe di piombo ha avuto un costruttore di copia (ad esempio, "Lead (Piombo otherLead)"), LeadWithImportCheckbox avrebbe ereditato questo e si può solo chiamare il costruttore di base di piombo nel costruttore LeadWithImportCheckbox - quindi senza necessità di LeadWithImportCheckbox di essere a conoscenza del dettagli di piombo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top