O membro '<método>' não pode ser acessado com uma referência de instância


195

Estou entrando em c # e estou tendo esse 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;
            }
        }
     }
 }

Eu tenho esse código em um UserControl:

using MyDataLayer.Section1;

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

Tudo funciona bem, exceto quando vou acessar Property1. O intellisense só dá-me " , e " como opções. Quando passo o mouse sobre o , o Visual Studio me dá esta explicação:EqualsGetHashCodeGetTypeToStringoItem.Property1

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

Não tenho certeza do que isso significa, eu pesquisei no Google, mas não consegui descobrir.

Respostas:


283

No C #, ao contrário do VB.NET e Java, você não pode acessar staticmembros com sintaxe de instância. Você deveria fazer:

MyClass.MyItem.Property1

para se referir a essa propriedade ou remover o staticmodificador Property1(que é o que você provavelmente deseja fazer). Para uma idéia conceitual sobre o que staticé, veja minha outra resposta .


45

Você pode acessar apenas membros estáticos usando o nome do tipo.

Portanto, você precisa escrever,

MyClass.MyItem.Property1

Ou (provavelmente é isso que você precisa fazer) crie Property1uma propriedade de instância removendo a staticpalavra-chave de sua definição.

As propriedades estáticas são compartilhadas entre todas as instâncias de sua classe, para que elas tenham apenas um valor. Da maneira como está definido agora, não há sentido em criar instâncias da sua classe MyItem.


Isso "Ou (provavelmente é isso que você precisa fazer) torna a Property1 uma propriedade de instância removendo a palavra-chave estática de sua definição". é a chave do sucesso !! Graças
tim687

29

Eu tive o mesmo problema - embora alguns anos depois, alguns possam achar úteis alguns indicadores:

Não use 'estático' gratuitamente!

Entenda o que 'estático' implica em termos de semântica em tempo de execução e tempo de compilação (comportamento) e sintaxe.

  • Uma entidade estática será construída automaticamente algum tempo antes de
    seu primeiro uso.

  • Uma entidade estática tem um local de armazenamento alocado e é
    compartilhado por todos os que acessam essa entidade.

  • Uma entidade estática pode ser acessada apenas pelo nome do tipo, não
    por uma instância desse tipo.

  • Um método estático não tem um argumento implícito 'this', assim como um método de instância. (E, portanto, um método estático tem menos
    sobrecarga de execução - um motivo para usá-los.)

  • Pense na segurança do encadeamento ao usar entidades estáticas.

Alguns detalhes sobre estática no MSDN:


4

Não há necessidade de usar estática neste caso, como explicado em detalhes. Você também pode inicializar sua propriedade sem o GetItem()método, exemplo dos dois abaixo:

namespace MyNamespace
{
    using System;

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

Consumindo:

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

não pode ser acessado com uma referência de instância

Isso significa que você está chamando um método STATIC e passando uma instância para ele. A solução mais fácil é remover o Static, por exemplo:

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


2

Sei que esse é um tópico antigo, mas passei apenas 3 horas tentando descobrir qual era o meu problema. Normalmente, eu sei o que esse erro significa, mas você pode encontrar isso de uma maneira mais sutil também. Meu problema era minha classe de cliente (aquela que chamava um método estático de uma classe de instância) tinha uma propriedade de um tipo diferente, mas com o mesmo nome do método estático. O erro relatado pelo compilador foi o mesmo relatado aqui, mas o problema foi basicamente a colisão de nomes.

Para qualquer pessoa que receba esse erro e nenhuma das opções acima ajude, tente qualificar totalmente sua classe de instância com o nome do namespace. .. () para que o compilador possa ver o nome exato que você quer dizer.


Achei isso útil. Eu tive uma colisão de nome e nem sabia disso. Assim que adicionei o espaço para nome antes da minha chamada de método, o problema foi resolvido.
Max

1

Verifique se o seu código contém um espaço para nome que corresponde à maior parte correta do seu nome de classe estática.

Dada a classe Bar estática , definida no espaço de nomes Foo , implementando um método Jump ou uma propriedade, é provável que você esteja recebendo um erro do compilador, porque também existe outro espaço de nome que termina em Bar . Sim, coisas de fishi ;-)

Nesse caso, significa usar uma barra Using; e uma chamada Bar.Jump () , portanto, uma das seguintes soluções deve atender às suas necessidades:

  • Qualifique totalmente o nome da classe estática com o namespace de acordo, que resulta na declaração Foo.Bar.Jump () . Você também precisará remover o Using Bar; declaração
  • Renomeie a barra de namespace por um nome diferente.

No meu caso, o seguinte erro do compilador ocorreu em um projeto de repositório EF ( Entity Framework ) em uma chamada Database.SetInitializer () :

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

Este erro ocorre quando adicionei um MyProject.ORM. O espaço para nome do banco de dados , cujo sufixo ( Banco de Dados ), como você notou, corresponde ao nome da classe Database .SetInitializer .

Nesse caso, como não tenho controle sobre a classe estática de banco de dados da EF e também gostaria de preservar meu espaço para nome personalizado, decidi qualificar totalmente a classe estática de banco de dados da EF com seu espaço de nome System.Data.Entity , que resultou no uso do seguinte comando, que compilação bem sucedida:

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

Espero que ajude



1

Isso causa o erro:

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

Esta é a correção:

MyClass.MyCoolStaticMethod();

Explicação:

Você não pode chamar um método estático de uma instância de um objeto. O ponto principal dos métodos estáticos é não estar vinculado a instâncias de objetos, mas persistir em todas as instâncias desse objeto e / ou ser usado sem nenhuma instância do objeto.


0
YourClassName.YourStaticFieldName

Para o seu campo estático seria semelhante a:

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

De outra classe, você pode acessar o campo staic da seguinte maneira:

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

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

         Console.ReadKey();
     }
  }

Talvez você possa traduzir sua solução no exemplo da pergunta e explicar um pouco sobre como os campos estáticos funcionam com relação às definições e instâncias de classe?
Noetix 27/02/19

Obrigado pelo seu comentário, que tal agora @Alex?
Hedego 27/02/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.