Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

C# เทียบเท่า C++ friend Keyword - Nested Class Pattern

C++ มี `friend` ให้ Function/Class อื่นเข้าถึง Private Members ได้ C# ไม่มี Keyword นี้ แต่ใช้ Nested Class Pattern แทน

C++ friend Concept

// C++
class MyClass {
private:
    int secret = 42;

    friend void FriendFunction(MyClass& obj); // Function Friend
    friend class FriendClass;                 // Class Friend
};

void FriendFunction(MyClass& obj) {
    cout << obj.secret; // เข้าถึง Private ได้
}

C# Equivalent: Nested Class (Inner Class)

Nested Class ใน C# สามารถเข้าถึง Private Members ของ Outer Class ได้

using System;

public class Outer
{
    private string _secret = "Outer Secret";

    // Nested Class - เข้าถึง Private ของ Outer ได้
    public class Inner
    {
        public void RevealSecret(Outer outer)
        {
            Console.WriteLine(outer._secret); // OK! เข้าถึง Private ได้
        }
    }

    public void Demo()
    {
        var inner = new Inner();
        inner.RevealSecret(this);
    }
}

public class Program
{
    public static void Main()
    {
        var outer = new Outer();
        outer.Demo(); // Output: Outer Secret

        // ภายนอก: ต้องผ่าน Outer Instance
        var inner = new Outer.Inner();
        inner.RevealSecret(outer);
    }
}

Private Nested Class (Encapsulation แบบเต็ม)


public class Outer
{
    private int _data = 100;

    // Private Nested Class - เห็นได้เฉพาะใน Outer
    private class InnerHelper
    {
        public void Process(Outer outer)
        {
            Console.WriteLine(outer._data * 2); // 200
        }
    }

    public void DoWork()
    {
        var helper = new InnerHelper();
        helper.Process(this);
    }
}

Factory Pattern ด้วย Nested Class


public class Widget
{
    private Widget(string id, string secret) // Private Constructor
    {
        Id = id;
        _secret = secret;
    }

    public string Id { get; }
    private string _secret;

    // Nested Factory - สร้าง Instance ได้
    public class Factory
    {
        public Widget Create(string id)
        {
            return new Widget(id, "Generated Secret");
        }
    }
}

// ใช้งาน
var widget = new Widget.Factory().Create("W001");

Alternative: Internal + InternalsVisibleTo (Assembly Level)


// Assembly A (Core)
[assembly: InternalsVisibleTo("AssemblyB.Tests")]

internal class InternalService { } // เข้าถึงได้จาก AssemblyB.Tests

// Assembly B (Tests) - เข้าถึง Internal ได้

Alternative: Interface + Internal Implementation


// Public Interface
public interface ISecretService
{
    void DoSecretWork();
}

// Internal Implementation - ซ่อนรายละเอียด
internal class SecretServiceImpl : ISecretService
{
    private string _key = "secret";
    public void DoSecretWork() => Console.WriteLine(_key);
}

// Factory คืน Interface
public static class ServiceFactory
{
    public static ISecretService Create() => new SecretServiceImpl();
}

เปรียบเทียบ

PatternAccess LevelUse Case
Nested Class (public)Outer Private + Public APIBuilder, Factory, Iterator
Nested Class (private)Outer Private OnlyHelper, Node, Strategy
InternalsVisibleToAssembly InternalUnit Testing
Interface + Internal ImplPublic Contract, Private ImplDI, Plugin, Encapsulation

สรุป

C# ไม่มี `friend` แต่ Nested Class ให้ Access Control ที่แม่นยำกว่า (ต่อ Class ไม่ใช่ต่อ Function) และ InternalsVisibleTo สำหรับ Testing เป็น Pattern มาตรฐานของ .NET