Non è possibile accedere al membro "<metodo>" con un riferimento all'istanza


195

Sto entrando in C # e sto riscontrando questo problema:

namespace MyDataLayer
{
    namespace Section1
    {
        public class MyClass
        {
            public class MyItem
            {
                public static string Property1{ get; set; }
            }
            public static MyItem GetItem()
            {
                MyItem theItem = new MyItem();
                theItem.Property1 = "MyValue";
                return theItem;
            }
        }
     }
 }

Ho questo codice su un UserControl:

using MyDataLayer.Section1;

public class MyClass
{
    protected void MyMethod
    {
        MyClass.MyItem oItem = new MyClass.MyItem();
        oItem = MyClass.GetItem();
        someLiteral.Text = oItem.Property1;
    }
}

Tutto funziona bene, tranne quando vado per accedere Property1. L'intellisense dà solo me " , , e " come opzioni. Quando passo con il mouse sopra , Visual Studio mi dà questa spiegazione:EqualsGetHashCodeGetTypeToStringoItem.Property1

MemberMyDataLayer.Section1.MyClass.MyItem.Property1.getcannot be accessed with an instance reference, qualify it with a type name instead

Non sono sicuro di cosa significhi, ho cercato su Google ma non sono riuscito a capirlo.

Risposte:


283

In C #, a differenza di VB.NET e Java, non è possibile accedere ai staticmembri con sintassi dell'istanza. Dovresti fare:

MyClass.MyItem.Property1

per fare riferimento a quella proprietà o rimuovere il staticmodificatore Property1(che è probabilmente quello che vuoi fare). Per un'idea concettuale di ciò che staticè, vedi la mia altra risposta .


45

Puoi accedere ai membri statici solo usando il nome del tipo.

Pertanto, è necessario scrivere,

MyClass.MyItem.Property1

Oppure (questo è probabilmente ciò che devi fare) crea Property1una proprietà di istanza rimuovendo la staticparola chiave dalla sua definizione.

Le proprietà statiche sono condivise tra tutte le istanze della loro classe, in modo che abbiano un solo valore. Il modo in cui è definito ora, non ha senso creare istanze della tua classe MyItem.


Questo "O (questo è probabilmente ciò che devi fare) rende Property1 una proprietà di istanza rimuovendo la parola chiave statica dalla sua definizione." è la chiave del successo !! Grazie
tim687,

29

Ho avuto lo stesso problema - anche se qualche anno dopo, alcuni potrebbero trovare utili alcuni suggerimenti:

Non usare 'statico' gratuitamente!

Comprendi cosa implica "statico" in termini sia di semantica (comportamento) che di tempo di esecuzione e di compilazione (sintassi).

  • Un'entità statica verrà costruita automaticamente qualche tempo prima del
    suo primo utilizzo.

  • Un'entità statica ha una posizione di archiviazione allocata e
    condivisa da tutti coloro che accedono a tale entità.

  • È possibile accedere a un'entità statica solo tramite il nome del suo tipo, non
    tramite un'istanza di quel tipo.

  • Un metodo statico non ha un argomento "questo" implicito, così come un metodo di istanza. (E quindi un metodo statico ha un
    sovraccarico di esecuzione inferiore - un motivo per usarli.)

  • Pensa alla sicurezza del thread quando usi entità statiche.

Alcuni dettagli su statico in MSDN:


4

Non è necessario utilizzare l'elettricità statica in questo caso, come spiegato a fondo. Puoi anche inizializzare la tua proprietà senza GetItem()metodo, esempio di entrambi di seguito:

namespace MyNamespace
{
    using System;

    public class MyType
    {
        public string MyProperty { get; set; } = new string();
        public static string MyStatic { get; set; } = "I'm static";
    }
}

Il consumo di:

using MyType;

public class Somewhere 
{
    public void Consuming(){

        // through instance of your type
        var myObject = new MyType(); 
        var alpha = myObject.MyProperty;

        // through your type 
        var beta = MyType.MyStatic;
    }
}       

3

impossibile accedere con un riferimento all'istanza

Significa che stai chiamando un metodo STATICO e gli passi un'istanza. La soluzione più semplice è rimuovere Static, ad esempio:

pubblico statico vuoto ExportToExcel (dati IEnumerable, string sheetName) {


2

So che questo è un vecchio thread, ma ho appena trascorso 3 ore a cercare di capire quale fosse il mio problema. Di solito so cosa significa questo errore, ma puoi anche imbatterti in un modo più sottile. Il mio problema era che la mia classe client (quella che chiamava un metodo statico da una classe di istanza) aveva una proprietà di un tipo diverso ma aveva lo stesso nome del metodo statico. L'errore segnalato dal compilatore era lo stesso riportato qui, ma il problema era fondamentalmente la collisione dei nomi.

Per chiunque ottenga questo errore e nessuno dei precedenti aiuta, prova a qualificare completamente la tua classe di istanza con il nome dello spazio dei nomi. .. () in modo che il compilatore possa vedere il nome esatto che intendi.


Ho trovato utile questo. Ho avuto una collisione di nome e non lo sapevo nemmeno. Non appena ho aggiunto lo spazio dei nomi prima della mia chiamata al metodo, il problema è stato risolto.
Max

1

Verifica se il codice contiene uno spazio dei nomi che la parte più a destra corrisponde al nome della tua classe statica.

Data la classe Bar statica , definita nello spazio dei nomi Foo , implementando un metodo Jump o una proprietà, è probabile che tu stia ricevendo un errore del compilatore perché c'è anche un altro spazio dei nomi che termina su Bar . Sì, roba da pesce ;-)

Se è così, significa che stai usando una barra di utilizzo; e una chiamata Bar.Jump () , quindi una delle seguenti soluzioni dovrebbe adattarsi alle tue esigenze:

  • Qualificare completamente il nome della classe statica con la relativa targhetta, che risulta nella dichiarazione Foo.Bar.Jump () . Sarà inoltre necessario rimuovere la barra di utilizzo; dichiarazione
  • Rinomina la barra dello spazio dei nomi con un nome diverso.

Nel mio caso, l'errore del compilatore seguente si è verificato su un progetto di repository EF ( Entity Framework ) su una chiamata Database.SetInitializer () :

Member 'Database.SetInitializer<MyDatabaseContext>(IDatabaseInitializer<MyDatabaseContext>)' cannot be accessed with an instance reference; qualify it with a type name instead MyProject.ORM

Questo errore suscita quando ho aggiunto un MyProject.ORM. Lo spazio dei nomi del database , che sufix ( Database ), come potresti notare, corrisponde al nome della classe Database .SetInitializer .

In questo, poiché non ho alcun controllo sulla classe statica del database EF e vorrei anche preservare il mio spazio dei nomi personalizzato, ho deciso di qualificare completamente la classe statica del database EF con il suo nome di sistema System.Data.Entity , che ha portato all'utilizzo del comando seguente, che compilazione riuscita:

System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(MyMigrationStrategy)

Spero che sia d'aiuto



1

Questo provoca l'errore:

MyClass aCoolObj = new MyClass();
aCoolObj.MyCoolStaticMethod();

Questa è la soluzione:

MyClass.MyCoolStaticMethod();

Spiegazione:

Non è possibile chiamare un metodo statico da un'istanza di un oggetto. L'intero punto dei metodi statici non deve essere legato alle istanze degli oggetti, ma piuttosto persistere attraverso tutte le istanze di quell'oggetto e / o essere usato senza alcuna istanza dell'oggetto.


0
YourClassName.YourStaticFieldName

Per il tuo campo statico sarebbe simile a:

public class StaticExample 
{
   public static double Pi = 3.14;
}

Da un'altra classe, puoi accedere al campo staic come segue:

    class Program
    {
     static void Main(string[] args)
     {
         double radius = 6;
         double areaOfCircle = 0;

         areaOfCircle = StaticExample.Pi * radius * radius;
         Console.WriteLine("Area = "+areaOfCircle);

         Console.ReadKey();
     }
  }

Forse potresti tradurre la tua soluzione nell'esempio della domanda e spiegare un po 'come funzionano i campi statici per quanto riguarda le definizioni e le istanze della classe?
Noetix,

Grazie per il tuo commento, che ne dici ora @Alex?
Hedego,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.