สมาชิก '<method>' ไม่สามารถเข้าถึงได้ด้วยการอ้างอิงอินสแตนซ์


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

ฉันไม่แน่ใจว่าสิ่งนี้หมายความว่าอย่างไรฉันทำ googling บางอย่าง แต่ไม่สามารถหาได้

คำตอบ:


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 (ข้อมูล IEnumerable, สตริงชีตชื่อ) {


2

ฉันรู้ว่านี่เป็นเธรดเก่า แต่ฉันใช้เวลา 3 ชั่วโมงพยายามหาว่าปัญหาของฉันคืออะไร ปกติแล้วฉันจะรู้ว่าข้อผิดพลาดนี้มีความหมายว่าอย่างไร แต่คุณสามารถใช้วิธีนี้ได้อย่างละเอียดยิ่งขึ้น ปัญหาของฉันคือชั้นลูกค้าของฉัน (หนึ่งที่เรียกวิธีการคงที่จากคลาสอินสแตนซ์) มีคุณสมบัติของประเภทที่แตกต่างกัน แต่ตั้งชื่อเช่นเดียวกับวิธีการคงที่ ข้อผิดพลาดที่รายงานโดยคอมไพเลอร์เหมือนกับรายงานที่นี่ แต่ปัญหาคือชื่อชนกันโดยทั่วไป

สำหรับใครก็ตามที่ได้รับข้อผิดพลาดนี้และไม่มีวิธีการใดที่ช่วยให้ลองกำหนดคลาสอินสแตนซ์ของคุณด้วยชื่อเนมสเปซ .. () เพื่อให้คอมไพเลอร์สามารถเห็นชื่อที่แน่นอนที่คุณหมายถึง


ฉันพบว่าสิ่งนี้มีประโยชน์ ฉันมีการชนกันของชื่อและไม่รู้ด้วยซ้ำ ทันทีที่ฉันเพิ่มเนมสเปซก่อนการเรียกเมธอดของฉันปัญหาได้รับการแก้ไข
สูงสุด

1

ตรวจสอบว่ารหัสของคุณมีเนมสเปซซึ่งส่วนใหญ่ตรงกับชื่อคลาสคงที่ของคุณ

ที่กำหนดคงที่บาร์ชั้นกำหนดไว้ใน namespace Foo , การใช้วิธีการกระโดดหรือสถานที่ให้โอกาสที่คุณจะได้รับการรวบรวมข้อผิดพลาดเพราะยังมี namespace สิ้นสุดในอีกบาร์ ใช่สิ่ง fishi ;-)

หากเป็นเช่นนั้นแสดงว่าคุณกำลังใช้บาร์อยู่ และการโทรแบบ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 namespace ซึ่ง sufix ( ฐานข้อมูล ) ตามที่คุณอาจสังเกตเห็นตรงกับชื่อคลาสฐานข้อมูล. SetInitializer

ในการนี้ตั้งแต่ผมไม่มีการควบคุมบนของ EF ฐานข้อมูลระดับคงที่และฉันยังต้องการที่จะรักษา namespace ที่กำหนดเองของฉันฉันตัดสินใจอย่างเต็มที่มีคุณสมบัติฐานข้อมูลระดับคงที่ของ EF กับ namepace ของ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;
}

จากคลาสอื่นคุณสามารถเข้าถึงฟิลด์ 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();
     }
  }

บางทีคุณอาจแปลโซลูชันของคุณเป็นตัวอย่างของคำถามและอธิบายเพียงเล็กน้อยเกี่ยวกับการทำงานของเขตข้อมูลคงที่เกี่ยวกับคำจำกัดความของคลาสและอินสแตนซ์
noetix

ขอบคุณสำหรับความคิดเห็นของคุณตอนนี้ @Alex เป็นอย่างไร?
Hedego
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.