Элемент <метод> не может быть доступен со ссылкой на экземпляр

196

Я вхожу в 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.

SLaks
источник
Это «Или (это, вероятно, то, что вам нужно сделать) сделать Property1 свойством экземпляра, удалив ключевое слово static из его определения». это ключ к успеху! Спасибо
tim687
29

У меня была та же проблема - хотя несколько лет спустя некоторые могут найти несколько полезных указателей:

Не используйте «статический» даром!

Понять, что подразумевается под «статическим» с точки зрения семантики (поведения) и синтаксиса времени исполнения и времени компиляции.

  • Статическая сущность будет автоматически создана за некоторое время до
    ее первого использования.

  • Статическому объекту выделено одно хранилище, которое
    используется всеми, кто имеет доступ к этому объекту.

  • Доступ к статическому объекту возможен только через имя его типа, а не
    через экземпляр этого типа.

  • Статический метод не имеет неявного аргумента this, как и метод экземпляра. (И поэтому у статического метода меньше
    накладных расходов на выполнение - одна из причин их использования.)

  • Подумайте о безопасности потоков при использовании статических объектов.

Некоторые подробности по статике в MSDN:

CarlH
источник
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 и передаете ему экземпляр. Самое простое решение - удалить Static, например:

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

Джереми Томпсон
источник
2

Я знаю, что это старая тема, но я потратил 3 часа, пытаясь выяснить, в чём была моя проблема. Обычно я знаю, что означает эта ошибка, но вы можете столкнуться с этим и более тонким способом. Моя проблема заключалась в том, что мой класс клиента (тот, который вызывал статический метод из класса экземпляра) имел свойство другого типа, но называлось так же, как статический метод. Ошибка, сообщенная компилятором, была такой же, как здесь, но проблема была в основном в конфликте имен.

Если кто-то еще получит эту ошибку и ничего из вышеперечисленного не поможет, попробуйте полностью указать класс вашего экземпляра с именем пространства имен. .. () чтобы компилятор мог видеть точное имя, которое вы имеете в виду.

диджей
источник
Я нашел это полезным. У меня было столкновение имен, и я даже не знал этого. Как только я добавил пространство имен перед вызовом метода, проблема была решена.
Макс
1

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

Учитывая статический класс Bar , определенный в пространстве имен Foo , реализующий метод Jump или свойство, скорее всего, вы получаете ошибку компилятора, потому что на Bar есть еще одно пространство имен, заканчивающееся . Да, рыбные штучки ;-)

Если это так, это означает, что вы используете панель использования; и вызов Bar.Jump () , поэтому одно из следующих решений должно соответствовать вашим потребностям:

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

В моем случае произошла следующая ошибка компилятора в проекте репозитория 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 Database, и я также хотел бы сохранить свое пользовательское пространство имен, я решил полностью квалифицировать статический класс EF Database с его пространством имен System.Data.Entity , в результате чего использовалась следующая команда, которая компиляция удалась:

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

Надеюсь, поможет

Хулио Нобре
источник
1

Я получил здесь поиск в Google для ошибки компилятора C # CS0176, из-за (дубликата) вопроса .

В моем случае ошибка произошла, потому что у меня был статический метод и метод расширения с тем же именем. Для этого см. Статический метод и метод расширения с одинаковым именем .

[Может быть, это должен был быть комментарий. Извините, что у меня пока недостаточно репутации.]

Пабло Н
источник
1

Это вызывает ошибку:

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

Это исправление:

MyClass.MyCoolStaticMethod();

Объяснение:

Вы не можете вызвать статический метод из экземпляра объекта. Весь смысл статических методов заключается не в том, чтобы быть привязанным к экземплярам объектов, а в том, чтобы сохранять его через все экземпляры этого объекта и / или использовать без каких-либо экземпляров объекта.

Андрей
источник
0
YourClassName.YourStaticFieldName

Ваше статическое поле будет выглядеть так:

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

Из другого класса вы можете получить доступ к полю staic следующим образом:

    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
источник
Возможно, вы могли бы перевести свое решение в пример вопроса и немного объяснить, как работают статические поля в отношении определений и экземпляров классов?
noetix
Спасибо за ваш комментарий, как насчет @Alex?
Хедего