C# 如何从封装在manager类中的基类派生类?

C# 如何从封装在manager类中的基类派生类?,c#,scope,encapsulation,derived-class,C#,Scope,Encapsulation,Derived Class,我有一个ManagerClass,它管理从抽象基类派生的类。我需要它,以便只有ManageClass可以访问基类上的某些方法。我还需要在ManagerClass范围之外访问某些方法。由于C#没有朋友,我将基类封装在ManagerClass中 问题是: 基类无法从中派生 将基类公开意味着允许DoStuff()和DoOtherStuff() 从ManagerClass范围之外调用,我不希望这样 我怎样才能做到这一点 public class ManagerClass {

我有一个ManagerClass,它管理从抽象基类派生的类。我需要它,以便只有ManageClass可以访问基类上的某些方法。我还需要在ManagerClass范围之外访问某些方法。由于C#没有朋友,我将基类封装在ManagerClass中

问题是:

  • 基类无法从中派生
  • 将基类公开意味着允许DoStuff()和DoOtherStuff() 从ManagerClass范围之外调用,我不希望这样
我怎样才能做到这一点

    public class ManagerClass
    {
        // This is a singleton class.
        static ManagerClass instance;

        public static T CreateBaseClass<T>() where T : BaseClass, new()
        {
            // Create and return a BaseClass.
            // Everything in BaseClass should be accessible here.
        }

        abstract class BaseClass()
        {
            public bool IsRunning { get; set; }

            virtual void DoStuff()
            {
                // Do stuff.
            }

            abstract void DoOtherStuff();
        }
    }

    public class DerivedClass : ManagerClass.BaseClass
    {
        public override void DoStuff()
        {
            // Do stuff.
        }

        public override void DoOtherStuff()
        {
            // Do other stuff.
        }
    }

    class TestClass
    {
        static void Main(string[] args)
        {
            // Assume singleton is already created here.
            BaseClass bc = ManagerClass.CreateBaseClass<DerivedClass>();
            // bc.IsRunning should be accessible
            // bc.DoStuff() and DoOtherStuff() should not be accessible
        }
    }
公共类管理器类
{
//这是一个单身班。
静态ManagerClass实例;
公共静态T CreateBaseClass(),其中T:BaseClass,new()
{
//创建并返回基类。
//基类中的所有内容都应该可以在这里访问。
}
抽象类基类()
{
公共bool正在运行{get;set;}
虚空DoStuff()
{
//做事。
}
抽象虚空DoOtherStuff();
}
}
公共类派生类:ManagerClass.BaseClass
{
公共覆盖无效DoStuff()
{
//做事。
}
公共覆盖无效DoOtherStuff()
{
//做其他事情。
}
}
类TestClass
{
静态void Main(字符串[]参数)
{
//假设这里已经创建了singleton。
BaseClass bc=ManagerClass.CreateBaseClass();
//bc.IsRunning应该是可访问的
//不应访问bc.DoStuff()和DoOtherStuff()
}
}

**

更新 **

好的,在发现无法使用泛型使委托为抽象类工作后,我尝试使用工厂接口。这也不起作用,因为我要么被迫将整个基类公开,要么无法从ManagerClass调用DoStuff()和DoOtherStuff()。然后我意识到我根本不需要工厂,因为DerivedClass调用基类构造函数,我可以在那里完成我的所有工作。。。有点

所以目前我有一个包装类,它包含一个基类和一个范围类,我可以使用它来存储委托或其他成员,只有ManagerClass才应该访问这些成员。公共成员仍然可以公开访问,但是ManagerClass现在必须通过包装器才能访问这些方法

新问题

现在唯一的问题是,我正在为基类的每个实例存储一个包装器。因为我只需要在我的BaseClassScope中存储委托,所以在调用基类静态构造函数时如何存储委托,然后如何使用该委托调用最重写的方法

    using System;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            ManagerClass.BaseClass[] dc = new DerivedClass[4];

            for (int i = 0; i < 4; i++)
            {
                dc[i] = new DerivedClass();

                // Is accessible from outside ManagerClass
                dc[i].IsRunning = true;

                // Is not accessible from outside ManagerClass
                // dc[i].DoStuff();
            }

            ManagerClass.TestManager();

            // Wait for input.
            Console.ReadKey(true);
        }
    }

    class ManagerClass
    {
        static List<BaseClassWrapper> managedList = new List<BaseClassWrapper>();

        public static void TestManager()
        {
            for (int i = 0; i < managedList.Count; i++)
            {
                // Is accessible from inside ManagerClass
                managedList[i].bcs.DoStuff();
                managedList[i].bcs.DoOtherStuff();
            }
        }

        class BaseClassScope
        {
            public Action DoStuff;
            public Action DoOtherStuff;

            public BaseClassScope(Action ds, Action dos)
            {
                DoStuff = ds;
                DoOtherStuff = dos;
            }
        }

        class BaseClassWrapper
        {
            public BaseClass bc;
            public BaseClassScope bcs;

            public BaseClassWrapper(BaseClass bc, BaseClassScope bcs)
            {
                this.bc = bc;
                this.bcs = bcs;
            }
        }

        public abstract class BaseClass
        {
            public BaseClass()
            {
                Console.WriteLine("BaseClass()");
                var bcs = new BaseClassScope(DoStuff, DoOtherStuff);
                var bcw = new BaseClassWrapper(this, bcs);
                managedList.Add(bcw);
            }

            public bool IsRunning { get; set; }

            protected virtual void DoStuff()
            {
                Console.WriteLine("BaseClass.DoStuff()");
            }

            protected abstract void DoOtherStuff();
        }
    }

    class DerivedClass : ManagerClass.BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("DerivedClass()");
        }

        protected override void DoStuff()
        {
            Console.WriteLine("DerivedClass.DoStuff()");
        }

        protected override void DoOtherStuff()
        {
            Console.WriteLine("DerivedClass.DoOtherStuff()");
        }
    }
使用系统;
使用System.Collections.Generic;
班级计划
{
静态void Main(字符串[]参数)
{
ManagerClass.BaseClass[]dc=新的派生类[4];
对于(int i=0;i<4;i++)
{
dc[i]=新的DerivedClass();
//可从外部ManagerClass访问
dc[i].IsRunning=true;
//无法从外部ManagerClass访问
//dc[i].DoStuff();
}
ManagerClass.TestManager();
//等待输入。
Console.ReadKey(true);
}
}
班级经理课堂
{
静态列表管理列表=新建列表();
公共静态void TestManager()
{
for(int i=0;i
所以我认为类似的方法可以奏效。在我写它的时候,它变得有点复杂,其中一些可能可以被清理,但基本上取决于嵌入类访问父类的私有静态变量的能力。我还没有机会测试它,但我认为这应该达到您想要的:

public class ManagerClass
{
    // This is a singleton class.
    static ManagerClass instance;
    private static Func<BaseClassFunctionHolder, BaseClass> _createBaseClass;

    public static T CreateBaseClass<T>() where T : BaseClass, new()
    {
        // Create and return a BaseClass.
        // Everything in BaseClass should be accessible here.

        //example
        BaseClassFunctionHolder holder = new BaseClassFunctionHolder();
        T baseClass = _createBaseClass(holder);

        //access to baseClass methods through holder.DoStuff, and holder.DoOtherStuff
        return baseClass;
    }

    private class BaseClassFunctionHolder
    {
        public Action DoStuff { get; set; }
        public Action DoOtherStuff { get; set; }
    }

    abstract class BaseClass
    {
        static BaseClass()
        {
            _createBaseClass = (holder) => new BaseClass(holder);
        }

        private BaseClass(BaseClassFunctionHolder holder)
        {
            holder.DoStuff = DoStuff;
            holder.DoOtherStuff = DoOtherStuff;
        }

        public bool IsRunning { get; set; }

        virtual void DoStuff()
        {
            // Do stuff.
        }

        abstract void DoOtherStuff();
    }
}

public class DerivedClass : ManagerClass.BaseClass
{
    override void DoStuff()
    {
        // Do stuff.
    }

    override void DoOtherStuff()
    {
        // Do other stuff.
    }
}

class TestClass
{
    static void Main(string[] args)
    {
        // Assume singleton is already created here.
        BaseClass bc = ManagerClass.CreateBaseClass<DerivedClass>();
        // bc.IsRunning should be accessible
        // bc.DoStuff() and DoOtherStuff() should not be accessible
    }
}
公共类管理器类
{
//这是一个单身班。
静态ManagerClass实例;
私有的
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            ManagerClass.BaseClass dc = new DerivedClass();
            ManagerClass.BaseClass adc = new AnotherDerivedClass();

            // Is accessible from outside ManagerClass
            dc.IsRunning = true;

            // Is not accessible from outside ManagerClass
            // dc.DoStuff();

            ManagerClass.TestManager();

            // Wait for input.
            Console.ReadKey(true);
        }
    }

    class ManagerClass
    {
        static ManagerClass instance;
        static List<BaseClass> managedList = new List<BaseClass>();
        static MethodInfo doStuffMethod = typeof(BaseClass).GetMethod("DoStuff", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.ExactBinding);
        static MethodInfo doOtherStuffMethod = typeof(BaseClass).GetMethod("DoOtherStuff", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.ExactBinding);

        public static ManagerClass Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ManagerClass();
                }

                return instance;
            }
        }

        public static void TestManager()
        {
            for (int i = 0; i < managedList.Count; i++)
            {
                // DoStuff() and DoOtherStuff need to be accessible only from the ManagerClass.
                // Invocation of the virtual methods calls the derived methods.
                doStuffMethod.Invoke(managedList[i], null);
                doOtherStuffMethod.Invoke(managedList[i], null);
            }
        }

        public abstract class BaseClass
        {
            public BaseClass()
            {
                Console.WriteLine("BaseClass()");
                managedList.Add(this);

                // All of ManagerClass fields are accessible from here:
                // instance, managedList, etc.
            }

            public bool IsRunning { get; set; }

            protected virtual void DoStuff()
            {
                Console.WriteLine("BaseClass.DoStuff()");
            }

            protected abstract void DoOtherStuff();
        }
    }

    class DerivedClass : ManagerClass.BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("DerivedClass()");

            // None of the ManagerClass fields are accessible from classes deriving from BaseClass:
            // instance, managedList, etc.
        }

        protected override void DoStuff()
        {
            Console.WriteLine("DerivedClass.DoStuff()");
        }

        protected override void DoOtherStuff()
        {
            Console.WriteLine("DerivedClass.DoOtherStuff()");
        }
    }

    class AnotherDerivedClass : ManagerClass.BaseClass
    {
        public AnotherDerivedClass()
        {
            Console.WriteLine("AnotherDerivedClass()");
        }

        protected override void DoStuff()
        {
            Console.WriteLine("AnotherDerivedClass.DoStuff()");
        }

        protected override void DoOtherStuff()
        {
            Console.WriteLine("AnotherDerivedClass.DoOtherStuff()");
        }
    }
    using System;
    using System.Collections.Generic;

    namespace testapp2
    {
        class Program
        {
            static void Main()
            {
                ClassA a = ClassA.Instance;
                ClassB b = ClassB.Instance;

                ManagerClass.TestManager();

                Console.ReadKey(true);
            }
        }
    }

    class ManagerClass
    {
        static ManagerClass instance;
        static Dictionary<Type, ManagedClass> managedList = new Dictionary<Type, ManagedClass>();

        public ManagerClass Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ManagerClass();
                }

                return instance;
            }
        }

        ManagerClass()
        {

        }

        public static void TestManager()
        {
            foreach (var kvp in managedList)
            {
                kvp.Value.doStuffCallback();
                kvp.Value.doOtherStuffCallback();
            }
        }

        public static void CreateManagedClass(Type type, Action doStuffCallback, Action doOtherStuffCallback)
        {
            managedList.Add(type, new ManagedClass(doStuffCallback, doOtherStuffCallback));
        }

        public static void DestroyManagedClass(Type type)
        {
            managedList.Remove(type);
        }

        class ManagedClass
        {
            public Action doStuffCallback;
            public Action doOtherStuffCallback;

            public ManagedClass(Action doStuffCallback, Action doOtherStuffCallback)
            {
                this.doStuffCallback = doStuffCallback;
                this.doOtherStuffCallback = doOtherStuffCallback;
            }
        }

        public abstract class ManagedClassBase<T> where T : class, new()
        {
            static T instance;

            public static T Instance
            {
                get
                {
                    if (instance == null)
                    {
                        instance = new T();
                    }

                    return instance;
                }
            }

            protected ManagedClassBase()
            {
                CreateManagedClass(typeof(T), DoStuff, DoOtherStuff);
            }

            ~ManagedClassBase()
            {
                instance = null;
            }

            protected abstract void DoStuff();
            protected abstract void DoOtherStuff();
        }
    }

    class ClassA : ManagerClass.ManagedClassBase<ClassA>
    {
        protected override void DoStuff()
        {
            Console.WriteLine("ClassA.DoStuff()");
        }

        protected override void DoOtherStuff()
        {
            Console.WriteLine("ClassA.DoOtherStuff()");
        }
    }

    class ClassB : ManagerClass.ManagedClassBase<ClassB>
    {
        protected override void DoStuff()
        {
            Console.WriteLine("ClassB.DoStuff()");
        }

        protected override void DoOtherStuff()
        {
            Console.WriteLine("ClassB.DoOtherStuff()");
        }
    }