Auf das Mitglied '<Methode>' kann nicht mit einer Instanzreferenz zugegriffen werden

195

Ich steige in C # ein und habe dieses Problem:

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

Ich habe diesen Code auf einem UserControl:

using MyDataLayer.Section1;

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

Alles funktioniert gut, außer wenn ich zum Zugriff gehe Property1. Die Intellisense nur gibt mir „ , , und “ als Optionen. Wenn ich mit der Maus darüber fahre, gibt mir Visual Studio folgende Erklärung:EqualsGetHashCodeGetTypeToStringoItem.Property1

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

Ich bin mir nicht sicher, was das bedeutet. Ich habe ein bisschen gegoogelt, konnte es aber nicht herausfinden.

Anders
quelle

Antworten:

283

In C # können Sie im Gegensatz zu VB.NET und Java nicht staticmit Instanzsyntax auf Mitglieder zugreifen . Du solltest tun:

MyClass.MyItem.Property1

um auf diese Eigenschaft zu verweisen oder den staticModifikator zu entfernen Property1(was Sie wahrscheinlich tun möchten). Eine konzeptionelle Vorstellung davon, was staticist, finden Sie in meiner anderen Antwort .

Mehrdad Afshari
quelle
45

Sie können nur mit dem Namen des Typs auf statische Elemente zugreifen.

Daher müssen Sie entweder schreiben,

MyClass.MyItem.Property1

Oder (dies ist wahrscheinlich das, was Sie tun müssen) Property1eine Instanzeigenschaft erstellen, indem Sie das staticSchlüsselwort aus seiner Definition entfernen .

Statische Eigenschaften werden von allen Instanzen ihrer Klasse gemeinsam genutzt, sodass sie nur einen Wert haben. So wie es jetzt definiert ist, macht es keinen Sinn, Instanzen Ihrer MyItem-Klasse zu erstellen.

SLaks
quelle
Dies "Oder (dies ist wahrscheinlich das, was Sie tun müssen) machen Sie Property1 zu einer Instanzeigenschaft, indem Sie das statische Schlüsselwort aus seiner Definition entfernen." ist der Schlüssel zum Erfolg !! Danke
tim687
29

Ich hatte das gleiche Problem - obwohl einige Jahre später einige Hinweise hilfreich finden könnten:

Verwenden Sie "statisch" nicht unentgeltlich!

Verstehen Sie, was 'statisch' sowohl in Bezug auf die Laufzeit- als auch die Kompilierungssemantik (Verhalten) und die Syntax bedeutet.

  • Eine statische Entität wird einige Zeit vor
    ihrer ersten Verwendung automatisch erstellt .

  • Einer statischen Entität ist ein Speicherort zugeordnet, der
    von allen Benutzern dieser Entität gemeinsam genutzt wird.

  • Auf eine statische Entität kann nur über ihren Typnamen zugegriffen werden, nicht
    über eine Instanz dieses Typs.

  • Eine statische Methode hat kein implizites 'this'-Argument, ebenso wie eine Instanzmethode. (Und deshalb hat eine statische Methode weniger Ausführungsaufwand
    - ein Grund, sie zu verwenden.)

  • Denken Sie an die Thread-Sicherheit, wenn Sie statische Entitäten verwenden.

Einige Details zur statischen Aufladung in MSDN:

CarlH
quelle
4

In diesem Fall muss keine statische Aufladung verwendet werden, wie ausführlich erläutert. Sie können Ihre Eigenschaft auch ohne GetItem()Methode initialisieren. Beispiel für beides unten:

namespace MyNamespace
{
    using System;

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

Konsumieren:

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;
    }
}       
Alan
quelle
3

kann nicht mit einer Instanzreferenz zugegriffen werden

Dies bedeutet, dass Sie eine STATIC-Methode aufrufen und eine Instanz übergeben. Die einfachste Lösung besteht darin, Static zu entfernen, z.

public static void ExportToExcel (IEnumerable data, string sheetName) {

Jeremy Thompson
quelle
2

Ich weiß, dass dies ein alter Thread ist, aber ich habe gerade 3 Stunden damit verbracht, herauszufinden, was mein Problem war. Normalerweise weiß ich, was dieser Fehler bedeutet, aber Sie können auch auf subtilere Weise darauf stoßen. Mein Problem war, dass meine Client-Klasse (die eine statische Methode aus einer Instanzklasse aufruft) eine Eigenschaft eines anderen Typs hatte, aber den gleichen Namen wie die statische Methode hatte. Der vom Compiler gemeldete Fehler war der gleiche wie hier, aber das Problem war im Grunde eine Namenskollision.

Versuchen Sie, Ihre Instanzklasse vollständig mit dem Namespace-Namen zu qualifizieren, damit alle anderen Benutzer diesen Fehler erhalten und keiner der oben genannten Punkte hilft. .. (), damit der Compiler den genauen Namen sehen kann, den Sie meinen.

DJ
quelle
Ich fand das hilfreich. Ich hatte eine Namenskollision und wusste es nicht einmal. Sobald ich den Namespace vor meinem Methodenaufruf hinzugefügt hatte, wurde das Problem behoben.
Max
1

Überprüfen Sie, ob Ihr Code einen Namespace enthält, der ganz rechts mit Ihrem statischen Klassennamen übereinstimmt.

Angesichts der statischen Bar- Klasse, die im Namespace Foo definiert ist und eine Methode Jump oder eine Eigenschaft implementiert , erhalten Sie wahrscheinlich einen Compilerfehler, da auch ein anderer Namespace auf Bar endet . Ja, Fischzeug ;-)

Wenn dem so ist, bedeutet dies, dass Sie eine Verwendungsleiste verwenden. und einen Bar.Jump () -Aufruf , daher sollte eine der folgenden Lösungen Ihren Anforderungen entsprechen:

  • Qualifizieren Sie den statischen Klassennamen vollständig mit dem entsprechenden Namespace, der sich aus der Deklaration Foo.Bar.Jump () ergibt . Sie müssen auch Using Bar entfernen . Aussage
  • Benennen Sie die Namespace- Leiste durch einen anderen Namen um.

In meinem Fall ist der folgende Compilerfehler bei einem EF- Repository-Projekt ( Entity Framework ) in einem Database.SetInitializer () -Aufruf aufgetreten :

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

Dieser Fehler tritt auf, wenn ich ein MyProject.ORM hinzufüge. Datenbank- Namespace, dessen Sufix ( Datenbank ), wie Sie vielleicht bemerkt haben, mit dem Klassennamen der Datenbank .SetInitializer übereinstimmt .

Da ich keine Kontrolle über die statische Datenbankklasse von EF habe und auch meinen benutzerdefinierten Namespace beibehalten möchte, habe ich beschlossen, die statische Datenbankklasse von EF vollständig mit dem Namensraum System.Data.Entity zu qualifizieren , was zur Verwendung des folgenden Befehls führte Kompilierung erfolgreich:

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

Ich hoffe es hilft

Julio Nobre
quelle
1

Ich habe hier nach C # -Compilerfehler CS0176 gegoogelt, durch (doppelte) Frage Referenzproblem der statischen Mitgliedsinstanz .

In meinem Fall ist der Fehler aufgetreten, weil ich eine statische Methode und eine Erweiterungsmethode mit demselben Namen hatte. Siehe dazu Statische Methode und Erweiterungsmethode mit demselben Namen .

[Vielleicht hätte dies ein Kommentar sein sollen. Tut mir leid, dass ich noch nicht genug Ruf habe.]

Pablo H.
quelle
1

Dies verursacht den Fehler:

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

Dies ist die Lösung:

MyClass.MyCoolStaticMethod();

Erläuterung:

Sie können keine statische Methode von einer Instanz eines Objekts aus aufrufen. Der Sinn statischer Methoden besteht darin, nicht an Instanzen von Objekten gebunden zu sein, sondern alle Instanzen dieses Objekts zu durchlaufen und / oder ohne Instanzen des Objekts zu verwenden.

Andrew
quelle
0
YourClassName.YourStaticFieldName

Denn Ihr statisches Feld würde aussehen wie:

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

Von einer anderen Klasse aus können Sie wie folgt auf das Feld staic zugreifen:

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

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

         Console.ReadKey();
     }
  }
Hedego
quelle
Vielleicht könnten Sie Ihre Lösung in das Beispiel der Frage übersetzen und ein wenig erklären, wie statische Felder in Bezug auf Klassendefinitionen und Instanzen funktionieren?
Noetix
Vielen Dank für Ihren Kommentar, wie wäre es jetzt mit @Alex?
Hedego