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