Thành viên '<phương thức>' không thể được truy cập bằng tham chiếu thể hiện


195

Tôi đang vào C # và tôi đang gặp vấn đề này:

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

Tôi có mã này trên UserControl:

using MyDataLayer.Section1;

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

Tất cả mọi thứ hoạt động tốt, ngoại trừ khi tôi truy cập Property1. IntelliSense chỉ mang lại cho tôi " , , và " như các tùy chọn. Khi tôi di chuột qua , Visual Studio cho tôi lời giải thích này:EqualsGetHashCodeGetTypeToStringoItem.Property1

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

Tôi không chắc điều này có nghĩa là gì, tôi đã làm một số việc nhưng không thể hiểu được.

Câu trả lời:


283

Trong C #, không giống như VB.NET và Java, bạn không thể truy cập staticcác thành viên bằng cú pháp cá thể. Bạn nên làm:

MyClass.MyItem.Property1

để tham chiếu đến thuộc tính đó hoặc xóa công cụ staticsửa đổi khỏi Property1(đó là những gì bạn có thể muốn làm). Đối với một ý tưởng khái niệm về những gì staticlà, xem câu trả lời khác của tôi .


45

Bạn chỉ có thể truy cập các thành viên tĩnh bằng cách sử dụng tên của loại.

Do đó, bạn cần phải viết,

MyClass.MyItem.Property1

Hoặc (đây có lẽ là những gì bạn cần làm) tạo Property1một thuộc tính thể hiện bằng cách xóa statictừ khóa khỏi định nghĩa của nó.

Các thuộc tính tĩnh được chia sẻ giữa tất cả các phiên bản của lớp của chúng, do đó chúng chỉ có một giá trị. Cách nó được định nghĩa bây giờ, không có điểm nào trong việc tạo bất kỳ trường hợp nào của lớp MyItem của bạn.


Điều này "Hoặc (đây có lẽ là những gì bạn cần làm) làm cho Property1 trở thành một thuộc tính thể hiện bằng cách xóa từ khóa tĩnh khỏi định nghĩa của nó." là chìa khóa thành công !! Cảm ơn
tim687

29

Tôi đã có cùng một vấn đề - mặc dù một vài năm sau đó, một số có thể tìm thấy một vài gợi ý hữu ích:

Không sử dụng 'tĩnh' một cách vô cớ!

Hiểu những gì 'tĩnh' ngụ ý về cả ngữ nghĩa thời gian chạy và thời gian biên dịch (hành vi) và cú pháp.

  • Một thực thể tĩnh sẽ được tự động xây dựng một thời gian trước khi
    sử dụng lần đầu tiên.

  • Một thực thể tĩnh có một vị trí lưu trữ được phân bổ và được
    chia sẻ bởi tất cả những người truy cập thực thể đó.

  • Một thực thể tĩnh chỉ có thể được truy cập thông qua tên loại của nó, không phải
    thông qua một thể hiện của loại đó.

  • Một phương thức tĩnh không có đối số ngầm 'này', cũng như một phương thức thể hiện. (Và do đó, một phương thức tĩnh có ít
    chi phí thực hiện hơn - một lý do để sử dụng chúng.)

  • Hãy suy nghĩ về an toàn luồng khi sử dụng các thực thể tĩnh.

Một số chi tiết về tĩnh trong MSDN:


4

Không cần sử dụng tĩnh trong trường hợp này như được giải thích kỹ lưỡng. Bạn cũng có thể khởi tạo tài sản của mình mà không cần GetItem()phương thức, ví dụ về cả hai cách dưới đây:

namespace MyNamespace
{
    using System;

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

Tiêu thụ:

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

không thể được truy cập với một tham chiếu thể hiện

Nó có nghĩa là bạn đang gọi một phương thức STATIC và truyền cho nó một thể hiện. Giải pháp đơn giản nhất là xóa Tĩnh, ví dụ:

công tĩnh khoảng trống ExportToExcel (dữ liệu IEnumerable, chuỗi SHEETNAME) {


2

Tôi biết đây là một chủ đề cũ, nhưng tôi chỉ mất 3 giờ để cố gắng tìm ra vấn đề của mình là gì. Tôi thường biết lỗi này có nghĩa là gì, nhưng bạn cũng có thể gặp phải vấn đề này một cách tinh tế hơn. Vấn đề của tôi là lớp máy khách của tôi (lớp gọi một phương thức tĩnh từ một lớp thể hiện) có một thuộc tính thuộc loại khác nhưng được đặt tên giống như phương thức tĩnh. Lỗi được trình biên dịch báo cáo giống như báo cáo ở đây, nhưng vấn đề cơ bản là xung đột tên.

Đối với bất kỳ ai khác nhận được lỗi này và không có sự giúp đỡ nào ở trên, hãy thử hoàn toàn đủ điều kiện lớp cá thể của bạn với tên không gian tên. .. () để trình biên dịch có thể thấy tên chính xác của bạn.


Tôi thấy điều này là hữu ích. Tôi đã có một vụ va chạm tên và thậm chí không biết điều đó. Ngay sau khi tôi thêm không gian tên trước khi gọi phương thức, vấn đề đã được giải quyết.
Tối đa

1

Kiểm tra xem mã của bạn có chứa một không gian tên mà phần lớn bên phải khớp với tên lớp tĩnh của bạn không.

Với một lớp Bar tĩnh , được định nghĩa trên không gian tên Foo , thực hiện một phương thức Jump hoặc một thuộc tính, rất có thể bạn đang nhận được lỗi trình biên dịch vì cũng có một không gian tên khác kết thúc trên Bar . Đúng, đồ cá ;-)

Nếu vậy, điều đó có nghĩa là bạn sử dụng Thanh Sử dụng; và một cuộc gọi Bar.Jump () , do đó, một trong những giải pháp sau sẽ phù hợp với nhu cầu của bạn:

  • Đủ điều kiện tên lớp tĩnh với tên nơi, kết quả trên khai báo Foo.Bar.Jump () . Bạn cũng sẽ cần phải xóa bằng cách sử dụng Bar;tuyên bố
  • Đổi tên không gian tên Bar bằng một tên khác.

Trong trường hợp của tôi, lỗi trình biên dịch foollowing xảy ra trong dự án kho lưu trữ EF ( Entity Framework ) trên một cuộc gọi Database.SetInitializer () :

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

Lỗi này khơi dậy khi tôi thêm MyProject.ORM. Không gian tên cơ sở dữ liệu , mà sufix ( Cơ sở dữ liệu ), như bạn có thể nhận thấy, khớp với tên lớp của Cơ sở dữ liệu. SetInitializer .

Trong trường hợp này, vì tôi không có quyền kiểm soát đối với lớp tĩnh Cơ sở dữ liệu của EF và tôi cũng muốn duy trì không gian tên tùy chỉnh của mình, tôi đã quyết định hoàn toàn đủ điều kiện lớp tĩnh Cơ sở dữ liệu của EF với tên gọi System.Data.Entity , kết quả là sử dụng lệnh sau, biên dịch thành công:

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

Hy vọng nó giúp


1

Tôi đã nhận được ở đây googling cho lỗi trình biên dịch C # CS0176, thông qua (trùng lặp) câu hỏi tham chiếu ví dụ thành viên tĩnh .

Trong trường hợp của tôi, lỗi xảy ra do tôi có một phương thức tĩnh và một phương thức mở rộng có cùng tên. Đối với điều đó, xem phương thức tĩnh và phương thức mở rộng có cùng tên .

[Có thể đây là một bình luận. Xin lỗi vì tôi chưa có đủ danh tiếng.]


1

Điều này gây ra lỗi:

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

Đây là cách khắc phục:

MyClass.MyCoolStaticMethod();

Giải trình:

Bạn không thể gọi một phương thức tĩnh từ một thể hiện của một đối tượng. Toàn bộ điểm của các phương thức tĩnh là không bị ràng buộc với các thể hiện của các đối tượng, mà thay vào đó để duy trì thông qua tất cả các phiên bản của đối tượng đó và / hoặc được sử dụng mà không có bất kỳ trường hợp nào của đối tượng.


0
YourClassName.YourStaticFieldName

Đối với trường tĩnh của bạn sẽ như sau:

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

Từ một lớp khác, bạn có thể truy cập vào trường cũ như sau:

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

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

         Console.ReadKey();
     }
  }

Có lẽ bạn có thể dịch giải pháp của mình thành ví dụ của câu hỏi và giải thích một chút về cách các trường tĩnh hoạt động liên quan đến các định nghĩa và thể hiện của lớp?
noetix

Cảm ơn bạn đã nhận xét của bạn, làm thế nào bây giờ @Alex?
Hedego
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.