C# 在泛型类C中继承#
我的大脑要爆炸了所以我想得到你的帮助。 请把我的问题想成程序员的难题。(事实上,这个问题对你们来说可能很简单,但对我来说不是。) 需要创建对象数组。例如,列出T是类的位置。(我将在下面描述T类)。此外,还需要创建包含此数组的“容器”以及使用此数组的一些方法。例如Add()、Remove(int IndexToRemove)。 类T必须有字段“Container”,这样,数组中的每个元素都可以知道它包含在哪里,并且可以访问它的容器的字段和方法。注意,在这种情况下,类T应该具有类型参数。事实上,事先不知道使用哪种容器类型。 让我们将这个类容器表示为A,将类元素(类T)表示为AUnit 代码: 嗯。如果你还在读,让我们继续。现在我们需要创建类B和类BUnit,它们与类A和类Aunit非常相似。最后,这个谜题的主要问题是我们如何做到这一点?当然,我可以复制粘贴和位修改A和A,并创建此代码C# 在泛型类C中继承#,c#,generics,inheritance,C#,Generics,Inheritance,我的大脑要爆炸了所以我想得到你的帮助。 请把我的问题想成程序员的难题。(事实上,这个问题对你们来说可能很简单,但对我来说不是。) 需要创建对象数组。例如,列出T是类的位置。(我将在下面描述T类)。此外,还需要创建包含此数组的“容器”以及使用此数组的一些方法。例如Add()、Remove(int IndexToRemove)。 类T必须有字段“Container”,这样,数组中的每个元素都可以知道它包含在哪里,并且可以访问它的容器的字段和方法。注意,在这种情况下,类T应该具有类型参数。事实上,事先
class B
{
public List<BUnit> Units; //Only Type Changing
public B()//ctor Name changing...
{
Units = new List<BUnit>();//Only Type Changing
}
public void Add()
{
this.Units.Add(new BUnit(this));//Only Type Changing
}
}
class BUnit
{
public int SomeField;
public B Container;//Only Type Changing
public string Name { get; private set; }
public A a; //NEW FIELD IS ADDED (just one)
public BUnit(B container) //Ctor Name and arguments type changing
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
this.a=new A(); //New ROW (just one)
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (BUnit unt in this.Container.Units) //Only Type Changing
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
此构造可用于创建“非齐次树”
救命,我需要有人帮忙,只是没有人…。[披头士乐队]
我用CopyPaste创建了B和BUnit。
但如何使用“宏定义”或“泛型”、继承或其他优雅风格的东西来实现呢?(C#语言)
我认为没有理由描述我所有失败的尝试和子问题。主题已太长。:)
如果您仍然阅读并理解我想问的问题,非常感谢。您需要实现一个基本类型,让我们称之为
UnitBase
,具有所有常见功能。我将按以下方式构造代码:
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
}
AUnit
和BUnit
类型创建基类:
public abstract class UnitBase
{
protected UnitBase()
{
}
public IContainer Container { get; private set; }
public int SomeField;
public string Name { get; private set; }
public void SetContainer(IContainer container)
{
Container = container;
}
public bool Rename(String newName)
{
if (Container.Contains(newName))
return false;
this.Name = newName; //No need to use String.Copy
return true;
}
}
public class BUnit : UnitBase
{
public int SpecificBProperty { get; private set; }
public BUnit()
{
}
}
类型,我已经删除了泛型类型,因为它在这个特殊情况下没有做太多工作,因为它在泛型类型中是不变的
此外,请记住,类型系统中的任何内容都无法避免以下情况:
public class Container : IContainer
{
public Container()
{
list = new List<UnitBase>();
}
private List<UnitBase> list;
public Q Add<Q>() where Q: UnitBase, new()
{
var newItem = Activator.CreateInstance<Q>();
newItem.SetContainer(this);
list.Add(newItem);
return newItem;
}
public IEnumerable<UnitBase> Units => list.Select(i => i);
public bool Contains(string name) =>
Units.Any(unit => unit.Name == name);
}
myContainer.Add<BUnit>();
myContainer.Add<AUnit>();
myContainer.Add();
myContainer.Add();
如果在同一个容器中有两种不同的类型不是一种选择,那么整个设置就会崩溃。这个问题也出现在以前的解决方案中,因此它不是什么新问题,我只是忘了指出它。,非常感谢您的建议。事实上,我不能说我完全理解你的答案,但利用你的想法,我已经做了我想做的
看起来我的变种很好用。然而,我想听听你们(和每个人)对下面描述的代码的看法。此结构的主要目标是创建非齐次树。那么你能从这方面估计一下吗
首先。我们需要为这两个类创建接口。我们在这里描述了所有“交叉使用”的函数
public interface IUnit<T>
{
string Name { get;}
void SetContainer(T t);
bool Rename(String newName);
}
public interface IContainer
{
bool IsNameBusy(String newName);
int Count { get; }
}
代码:UnitBase
class UnitBase<T> : IUnit<T> where T : IContainer
{
protected T Container;
public string Name { get; private set; }
public UnitBase()
{
this.Name = "Default";
}
public void SetContainer(T container)
{
this.Container = container;
}
public bool Rename(String newName)
{
bool res = Container.IsNameBusy(newName);
if (!res) this.Name = String.Copy(newName);
return !res;
}
}
class UnitBase:IUnit其中T:IContainer
{
受保护的T形容器;
公共字符串名称{get;private set;}
公共单位库()
{
this.Name=“Default”;
}
公共容器(T容器)
{
this.Container=Container;
}
公共bool重命名(字符串newName)
{
bool res=Container.IsNameBusy(newName);
如果(!res)this.Name=String.Copy(newName);
返回!res;
}
}
下一个。创建容器基
集装箱基础应:
1) 具有IContainer接口
2) 包含有关其将包含的内容的信息:
... where U : IUnit<C>, new()
。。。其中U:IUnit,new()
3) 还有。。。。有关于它本身的信息。我们需要将此信息作为参数传递给SetContainer()方法
代码容器库:
class ContainerBase<U, C> : IContainer //U - Unit Class. C-Container Class
where U : IUnit<C>, new()
where C : ContainerBase<U, C>
{
protected List<U> Units;
public U this[int index] { get { return Units[index]; } }
public ContainerBase()//ctor
{
this.Units = new List<U>();
}
public void Add()
{
this.Units.Add(new U());
this.Units.Last().SetContainer(((C)this));//may be a bit strange but actualy this will have the same type as <C>
}
public bool IsNameBusy(String newName)
{
bool res = false;
foreach (var unt in this.Units)
{
if (unt.Name == newName)
{
res = true;
break;
}
}
return res;
}
public int Count { get { return this.Units.Count; } }
}
类容器基:IContainer//U-单元类。集装箱类
其中U:IUnit,new()
其中C:ContainerBase
{
受保护名单单位;
公共U这个[int索引]{get{返回单位[index];}
公共容器基()//
{
this.Units=新列表();
}
公共无效添加()
{
这个.Units.Add(新的U());
this.Units.Last().SetContainer(((C)this));//可能有点奇怪,但实际上它的类型与
}
public bool IsNameBusy(字符串newName)
{
bool res=假;
foreach(此.Units中的变量unt)
{
如果(unt.Name==newName)
{
res=真;
打破
}
}
返回res;
}
公共整数计数{get{返回this.Units.Count;}}
}
演员((TContainer)(this))可能有点奇怪。但是使用ContainerBase时,我们应该始终使用NewInheritorContainer。所以这个演员是什么都不做…看起来像
最后。这些类可以像本例中那样使用
class SheetContainer : ContainerBase<SheetUnit,SheetContainer> {public SheetContainer(){}}
class SheetUnit : UnitBase<SheetContainer>
{
public CellContainer Cells;
public PictureContainer Pictures;
public SheetUnit()
{
this.Cells = new CellContainer();
this.Pictures = new PictureContainer();
}
}
class CellContainer : ContainerBase<CellUnit, CellContainer> { public CellContainer() { } }
class CellUnit : UnitBase<CellContainer>
{
public string ValuePr;//Private Field
private const string ValuePrDefault = "Default";
public string Value//Property for Value
{
//All below are Just For Example.
get
{
return this.ValuePr;
}
set
{
if (String.IsNullOrEmpty(value))
{
this.ValuePr = ValuePrDefault;
}
else
{
this.ValuePr = String.Copy(value);
}
}
}
public CellUnit()
{
this.ValuePr = ValuePrDefault;
}
}
class PictureContainer : ContainerBase<PictureUnit, PictureContainer> { public PictureContainer() { } }
class PictureUnit : UnitBase<PictureContainer>
{
public int[,] Pixels{get;private set;}
public PictureUnit()
{
this.Pixels=new int[,]{{10,20,30},{11,12,13}};
}
public int GetSizeX()
{
return this.Pixels.GetLength(1);
}
public int GetSizeY()
{
return this.Pixels.GetLength(0);
}
public bool LoadFromFile(string path)
{
return false;
}
}
static void Main(string[] args)
{
SheetContainer Sheets = new SheetContainer();
Sheets.Add();
Sheets.Add();
Sheets.Add();
Sheets[0].Pictures.Add();
Sheets[1].Cells.Add();
Sheets[2].Pictures.Add();
Sheets[2].Cells.Add();
Sheets[2].Cells[0].Value = "FirstTest";
bool res= Sheets[0].Rename("First");//res=true
res=Sheets[2].Rename("First");//res =false
int res2 = Sheets.Count;
res2 = Sheets[2].Pictures[0].Pixels[1, 2];//13
res2 = Sheets[2].Pictures.Count;//1
res2 = Sheets[1].Pictures.Count;//0
res2 = Sheets[0].Pictures[0].GetSizeX();//3
Console.ReadKey();
}
class SheetContainer:ContainerBase{public SheetContainer(){}
类别单位:UnitBase
{
公共细胞和容器细胞;
公共图片容器图片;
公共小型张组()
{
this.Cells=新的CellContainer();
this.Pictures=新的PictureContainer();
}
}
类CellContainer:ContainerBase{public CellContainer(){}
类别单元:UnitBase
{
公共字符串ValuePr;//私有字段
private const string ValuePrDefault=“Default”;
公共字符串值//值的属性
{
//以下所有内容仅为示例。
得到
{
返回此.ValuePr;
}
设置
{
if(String.IsNullOrEmpty(value))
{
class UnitBase<T> : IUnit<T> where T : IContainer
SetContainer(T container).
class UnitBase<T> : IUnit<T> where T : IContainer
{
protected T Container;
public string Name { get; private set; }
public UnitBase()
{
this.Name = "Default";
}
public void SetContainer(T container)
{
this.Container = container;
}
public bool Rename(String newName)
{
bool res = Container.IsNameBusy(newName);
if (!res) this.Name = String.Copy(newName);
return !res;
}
}
... where U : IUnit<C>, new()
class ContainerBase<U, C> : IContainer //U - Unit Class. C-Container Class
where U : IUnit<C>, new()
where C : ContainerBase<U, C>
{
protected List<U> Units;
public U this[int index] { get { return Units[index]; } }
public ContainerBase()//ctor
{
this.Units = new List<U>();
}
public void Add()
{
this.Units.Add(new U());
this.Units.Last().SetContainer(((C)this));//may be a bit strange but actualy this will have the same type as <C>
}
public bool IsNameBusy(String newName)
{
bool res = false;
foreach (var unt in this.Units)
{
if (unt.Name == newName)
{
res = true;
break;
}
}
return res;
}
public int Count { get { return this.Units.Count; } }
}
class SheetContainer : ContainerBase<SheetUnit,SheetContainer> {public SheetContainer(){}}
class SheetUnit : UnitBase<SheetContainer>
{
public CellContainer Cells;
public PictureContainer Pictures;
public SheetUnit()
{
this.Cells = new CellContainer();
this.Pictures = new PictureContainer();
}
}
class CellContainer : ContainerBase<CellUnit, CellContainer> { public CellContainer() { } }
class CellUnit : UnitBase<CellContainer>
{
public string ValuePr;//Private Field
private const string ValuePrDefault = "Default";
public string Value//Property for Value
{
//All below are Just For Example.
get
{
return this.ValuePr;
}
set
{
if (String.IsNullOrEmpty(value))
{
this.ValuePr = ValuePrDefault;
}
else
{
this.ValuePr = String.Copy(value);
}
}
}
public CellUnit()
{
this.ValuePr = ValuePrDefault;
}
}
class PictureContainer : ContainerBase<PictureUnit, PictureContainer> { public PictureContainer() { } }
class PictureUnit : UnitBase<PictureContainer>
{
public int[,] Pixels{get;private set;}
public PictureUnit()
{
this.Pixels=new int[,]{{10,20,30},{11,12,13}};
}
public int GetSizeX()
{
return this.Pixels.GetLength(1);
}
public int GetSizeY()
{
return this.Pixels.GetLength(0);
}
public bool LoadFromFile(string path)
{
return false;
}
}
static void Main(string[] args)
{
SheetContainer Sheets = new SheetContainer();
Sheets.Add();
Sheets.Add();
Sheets.Add();
Sheets[0].Pictures.Add();
Sheets[1].Cells.Add();
Sheets[2].Pictures.Add();
Sheets[2].Cells.Add();
Sheets[2].Cells[0].Value = "FirstTest";
bool res= Sheets[0].Rename("First");//res=true
res=Sheets[2].Rename("First");//res =false
int res2 = Sheets.Count;
res2 = Sheets[2].Pictures[0].Pixels[1, 2];//13
res2 = Sheets[2].Pictures.Count;//1
res2 = Sheets[1].Pictures.Count;//0
res2 = Sheets[0].Pictures[0].GetSizeX();//3
Console.ReadKey();
}