До учасника "<метод>" не можна отримати посилання на екземпляр


195

Я вступаю в C # і у мене виникає таке питання:

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

Я маю цей код на UserControl:

using MyDataLayer.Section1;

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

Все працює добре, крім випадків, коли я йду на доступ Property1. IntelliSense тільки дає мені « , і » в якості опції. Коли я клацну мишкою на , Visual Studio дає мені таке пояснення:EqualsGetHashCodeGetTypeToStringoItem.Property1

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

Я не впевнений, що це означає, я зробив якийсь гугл, але не зміг це зрозуміти.

Відповіді:


283

У C #, на відміну від VB.NET та Java, ви не можете отримати доступ до staticчленів із синтаксисом екземпляра. Ви повинні зробити:

MyClass.MyItem.Property1

посилатися на це властивість або видалити staticмодифікатор з цього Property1(що, напевно, ви хочете зробити). Для концептуальної ідеї про те, що staticє, дивіться іншу мою відповідь .


45

Ви можете отримати доступ до статичних членів лише за допомогою імені типу.

Тому вам потрібно або написати,

MyClass.MyItem.Property1

Або (це, мабуть, те, що вам потрібно зробити), зробіть Property1властивість екземпляра, видаливши staticключове слово з його визначення.

Статичні властивості поділяються між усіма примірниками їх класу, так що вони мають лише одне значення. Спосіб, визначений зараз, не має сенсу робити будь-які екземпляри вашого класу MyItem.


Це "Або (це, мабуть, те, що вам потрібно зробити), зробить Property1 властивістю екземпляра, видаливши статичне ключове слово з його визначення." це запорука успіху !! Спасибі
tim687

29

У мене був той самий випуск - хоча через кілька років деякі можуть виявити корисні кілька покажчиків:

Не використовуйте «статичну» безкоштовно!

Зрозумійте, що означає "статичне" з точки зору як часу виконання, так і складання семантики часу (поведінки) та синтаксису.

  • Статична сутність буде автоматично побудована за деякий час до
    її першого використання.

  • Статичному об'єкту виділено одне місце зберігання, яке
    ділиться всіма, хто має доступ до цієї сутності.

  • До статичного об'єкту можна отримати доступ лише через його ім'я типу, а не
    через примірник цього типу.

  • Статичний метод не містить неявного аргументу, як і метод екземпляра. (І тому статичний метод має менші
    накладні витрати - одна причина їх використання.)

  • Подумайте про безпеку ниток при використанні статичних об'єктів.

Деякі деталі щодо статики в MSDN:


4

Не потрібно використовувати статику в цьому випадку, як це ретельно пояснено. Ви також можете ініціалізувати свою власність без GetItem()методу, наприклад обидва нижче:

namespace MyNamespace
{
    using System;

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

Споживання:

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

не можна отримати посилання на екземпляр

Це означає, що ви викликаєте метод STATIC і передаєте йому екземпляр. Найпростішим рішенням є видалення статичного, наприклад:

загальнодоступна статична недійсна ExportToExcel (IEbroce data, string stringName) {


2

Я знаю, що це стара тема, але я просто витратив 3 години, намагаючись зрозуміти, у чому моя проблема. Я звичайно знаю, що означає ця помилка, але ви можете зіткнутися і з цим більш тонким способом. Моя проблема - мій клієнтський клас (той, що викликає статичний метод з класу екземпляра), мав властивість іншого типу, але названий таким же, як і статичний метод. Помилка, про яку повідомив компілятор, була такою ж, як і тут, але проблема полягала в зіткненні з назвою.

Для всіх, хто отримує цю помилку, і жодне з перерахованих вище не допомагає, спробуйте повністю кваліфікувати свій клас примірника з назвою простору імен. .. (), щоб компілятор міг бачити точну назву, яку ви маєте на увазі.


Я вважаю це корисним. У мене було зіткнення імені і навіть не знав цього. Як тільки я додав простір імен перед викликом методу, проблема була вирішена.
Макс

1

Перевірте, чи містить ваш код простір імен, який в правій частині відповідає вашому імені статичного класу.

Враховуючи статичний клас Bar , визначений у просторі імен Foo , реалізуючи метод Jump або властивість, ймовірно, ви отримуєте помилку компілятора, оскільки на Bar також існує інша область імен . Так, рибалки ;-)

Якщо це так, це означає, що ви використовуєте панель використання; і виклик Bar.Jump () , тому одне з наступних рішень повинно відповідати вашим потребам:

  • Повністю кваліфікуйте статичну назву класу відповідно до простору імен , що призводить до оголошення Foo.Bar.Jump () . Вам також потрібно буде видалити за допомогою панелі; заява
  • Перейменуйте панель простору імен різними іменами.

У моєму випадку помилка компілятора, що утворилася, сталася в проекті сховища EF ( Entity Framework ) на виклику Database.SetInitializer () :

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

Ця помилка виникла, коли я додав MyProject.ORM. Простір імен бази даних , суфікс ( Database ), як ви могли помітити, відповідає імені класу Database .SetInitializer .

У зв'язку з цим, оскільки у мене немає контролю над статичним класом бази даних EF, і я також хотів би зберегти свій власний простір імен, я вирішив повністю кваліфікувати статичний клас бази даних EF зі своїм простором імен System.Data.Entity , в результаті чого було використано наступну команду, яка компіляція успішна:

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

Сподіваюся, це допомагає


1

Я потрапив сюди googling для C # компілятора помилки CS0176, через (дублікат) питання Статичний довідник екземпляра члена учасника .

У моєму випадку помилка сталася тому, що у мене був статичний метод та метод розширення з тим же ім’ям. Для цього див. Статичний метод та метод розширення з однойменною назвою .

[Може бути, це мав бути коментар. Вибачте, що у мене ще недостатньо репутації.]


1

Це спричиняє помилку:

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

Це виправлення:

MyClass.MyCoolStaticMethod();

Пояснення:

Ви не можете викликати статичний метод з екземпляра об'єкта. Вся суть статичних методів полягає в тому, щоб не прив'язувати до примірників об'єктів, а замість цього зберігатись у всіх екземплярах цього об'єкта та / або використовуватись без жодних екземплярів об'єкта.


0
YourClassName.YourStaticFieldName

Для вашого статичного поля це виглядатиме так:

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

З іншого класу ви можете отримати доступ до статичного поля таким чином:

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

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

         Console.ReadKey();
     }
  }

Можливо, ви могли б перекласти своє рішення на приклад запитання та трохи пояснити, як працюють статичні поля щодо визначень та екземплярів класу?
noetix

Дякую за Ваш коментар, а як же зараз @Alex?
Гедего
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.