Domanda

Ancora una volta Disclaimer Disclaimer ancora imparando C # e programmazione orientata agli oggetti in genere quindi spero che sarete pazienti con me:)

Al momento sto lavorando con un CMS che ha una chiamata FileVersion classe che contiene essenzialmente un elenco di proprietà relative a un file, come il nome del file, tipo di file, dimensione in byte, id, data caricato, è-ultima-versione, etc.

Un elenco di FileVersions è contenuta all'interno di un File, che ha il proprio ID univoco. Quando si desidera scaricare un file particolare dal CMS, l'URL viene costruito utilizzando qualcosa di simile al seguente:

string URL = "/files/"+file.id.toString()+"/"+file.fileVersion.Last().filename;

Ora per un particolare controllo su cui sto lavorando (si occupano specificamente di file che sono i documenti), ha senso di essere in grado di memorizzare l'URL insieme a tutte le altre informazioni FileVersion per un uso successivo. Quindi quello che ho deciso di fare è creare la mia classe chiamata DocumentVersion che si estende FileVersion. Questo è ciò che sembra:

public partial class DocumentVersion : FileVersion
{
    public DocumentVersion() : base() { }
    public string link;
}

Ora Vorrei sottolineare, che sembra che non ho bisogno per implementare un'interfaccia qui - ma non prendo come vangelo, è per questo che sono qui.

Tuttavia quando provo a lanciare la mia FileVersion come DocumentVersion in questo modo:

DocumentVersion dv = ((DocumentVersion)fileversion);

ottengo la seguente eccezione:

  

Impossibile eseguire il cast oggetto di tipo   'Foo.CMS.FileVersion' di digitare   'CoA.DocumentVersion'.

Il mio sentore è che è perché sto cercando di estendere una classe in uno spazio dei nomi diverso da dove risiede originali, ma come ho detto, OOP è relativamente nuovo per me così ho potuto essere sbagliato.

Grazie in anticipo per il vostro aiuto. Questa comunità è stato così prezioso! Spero solo che una volta che ho più esperto fino posso dare un po 'indietro:).

È stato utile?

Soluzione

Stai cercando di downcast? vale a dire fare un FileVersion esistente e dichiarare di essere un DocumentVersion?

Se è così, non è possibile farlo, dal momento che quello che hai è altro che un FileVersion.

Invece è necessario creare un nuovo oggetto DocumentVersion. Il tuo costruttore DocumentVersion avrà gli argomenti necessari per un FileVersion e poi chiamare il costruttore FileVersion via base().

Si noti che se si dispone di un oggetto FileVersion esistente, può essere utile un oggetto per avvolgere questo, piuttosto che avere un oggetto che ne deriva. per esempio. il vostro DocumentVersion non deriverebbe da FileVersion, ma contengono un riferimento privato ad una FileVersion, oltre a dati aggiuntivi, come richiesto. Che può essere più appropriato in questo scenario.

es. (In termini OO questo è composizione )

public class DocumentVersion {
   private FileVersion fv;
   private String url;
   public DocumentVersion(FileVersion fv, String url) {
      this.fv = fv;
      this.url = url;
   }
}

qui per ulteriori informazioni sulla composizione.

Altri suggerimenti

Non si può lanciare la vostra FileVersion per DocumentVersion perché la variabile FileVersion contiene un FileVersion, non un DocumentVersion. Inheritance significa quanto segue:

  • Ogni DocumentVersion è un FileVersion, ma
  • non ogni FileVersion è un DocumentVersion!

Se l'oggetto è stato creato come un FileVersion, è solo una FileVersion. Periodo. Se è stato creato come un DocumentVersion, è possibile utilizzarlo ovunque in cui si usa un FileVersion (vedi sopra regola # 1), e è possibile utilizzare le funzionalità DocumentVersion di esso.

Così, quando creazione l'oggetto FileVersion, è necessario creare un DocumentVersion invece (se si ha il controllo su quella parte del codice), poi il cast funzionerà. Quei DocumentVersions potrebbero essere memorizzati nella stessa lista come FileVersions, dal momento che ogni DocumentVersion è anche un FileVersion.


EDIT: Dal momento che queste due regole sono così vitale importanza per la comprensione del principio OO, mi permetta loro di illustrare con un esempio: DocumentVersion = cane e FileVersion = animali. Poi sarebbero le regole di cui sopra: (1) Ogni cane è un animale, ma (2) Non tutti gli animali è un cane. Quindi, è possibile creare una lista di animali, memorizzare tutti i tipi di animali in là (cani, gatti, cose che sono solo "animale", ...), ma non è possibile lanciare una variabile di tipo animale a un cane, a meno che ciò è in là è stato creato come un cane (o come un barboncino (classe barboncino: cane), che è una cane dalla regola (1)).

In termini OO: Se si memorizza un cane in una variabile di tipo animale, allora il tipo statico dell'oggetto è "animale", e il tipo dinamico è "cane". Si può lanciare solo un elemento di un certo tipo T se il suo tipo dinamico è T o un sottotipo della stessa.

Non si può fare il padre (FileVersion) di agire come il figlio (DocumentVersion).
Solo vica versa => è possibile effettuare figlio come il padre.

(FileVersion) documentVersion //
valida (DocumentVersion) FileVersion // valido (perché FileVersion non può sapere di roba che tipo derivato ha)

Ecco basi OOP.

DocumentVersion dv = null;

if (fileversion is DocumentVersion)
{
    dv = fileversion as DocumentVersion;
}

(Come la maggior parte delle risposte hanno detto, non si può lanciare il backup - FileVersion non ha idea di ciò che un DocumentVersion è).

Un modo per aggirare l'ostacolo è quello di copiare i campi nel costruttore di DocumentVersion

public partial class DocumentVersion : FileVersion
{
    public DocumentVersion() : base() { }

    public DocumentVersion(FileVersion version) : this()
    {
        this.id = version.id;
        // etc.
    }

    public string Link { get;set; }
}

O creare un metodo statico su DocumentVersion che restituisce un DocumentVersion dal FileVersion si fornisce, per esempio:

public static void New(FileVersion version)
{
    this.id = version.id;
    // etc.
}

Un'altra tecnica menzionata, è composizione. Si memorizza il FileVersion come una proprietà in DocumentVersion

public class DocumentVersion
{
    public FileVersion FileVersion { get;set; }
    public string Link { get;set; }
}

Dal momento che non è possibile convertire un FileVersion ad un DocumentVersion e tutto quello che dovete fare è aggiungere un metodo per ottenere l'URL, è possibile creare un metodo di estensione che prende una FileVersion:

public static string GetLink(this FileVersion fileVersion) {
  return "/files/"+fileVersion.id.ToString()+"/"+fileVersion.FileVersion.Last().Filename
}

Nota: questo funziona solo se si utilizza C # 3.0

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