C# 泛型类的泛型父类
我用一个虚构的例子来说明这一点。比如说,我有一个小部件类,比如:C# 泛型类的泛型父类,c#,generics,C#,Generics,我用一个虚构的例子来说明这一点。比如说,我有一个小部件类,比如: abstract class Widget { Widget parent; } 现在,我的其他类将从这个Widget类派生,但是假设我想在定义派生类型时在类中添加一些约束,这样只有特定“类型”的Widget可以是特定类型的Widget的父类 例如,我从Widget类派生了另外两个Widget,WidgetParent和WidgetChild。在定义子类时,我想将父类的类型定义为WidgetParent,这样我就不必每次使用它时
abstract class Widget
{
Widget parent;
}
现在,我的其他类将从这个Widget类派生,但是假设我想在定义派生类型时在类中添加一些约束,这样只有特定“类型”的Widget可以是特定类型的Widget的父类
例如,我从Widget类派生了另外两个Widget,WidgetParent和WidgetChild。在定义子类时,我想将父类的类型定义为WidgetParent,这样我就不必每次使用它时都对父类进行类型转换
确切地说,我想做的是:
// This does not works!
class Widget<PType>: where PType: Widget
{
PType parent;
}
class WidgetParent<Widget>
{
public void Slap();
}
class WidgetChild<WidgetParent>
{
}
我想这样使用它(如果我可以使用泛型):
我认为没有一种语言机制允许你这么做 但是,您可能希望使用将类的构造与类本身分开 比如说,创建一个WidgetFactory类
class WidgetFactory
{
Widget CreateWidget()
{
return new Widget();
}
}
而对于儿童班,你也可以制作他们的工厂。例如,WidgetParentFactory或WidgetChildFactory,或者您可以创建一个通用工厂:
class WidgetFactory<T> where T : Widget
{
T CreateWidget()
{
return new T();
}
}
类WidgetFactory,其中T:Widget
{
T CreateWidget()
{
返回新的T();
}
}
然后,通过CreateWidget()方法可以控制类实例化,从而无法创建无效的子类型
class WidgetFactory<T> where T : Widget
{
T CreateWidget()
{
if (/*check the type T inheritance here*/)
return new T();
else
throw new Exception("Invalid inheritance");
}
}
类WidgetFactory,其中T:Widget
{
T CreateWidget()
{
如果(/*请在此处检查类型T继承*/)
返回新的T();
其他的
抛出新异常(“无效继承”);
}
}
这应该对你有好处
p、 您是否愿意详细说明您为什么要这样做?您应该能够通过仍然使用非通用类
小部件
并使小部件
从中派生出来来使用您得到的代码:
public abstract class Widget
{
}
public abstract class Widget<T> : Widget where T : Widget
{
}
公共抽象类小部件
{
}
公共抽象类Widget:Widget,其中T:Widget
{
}
然后,您需要确定哪些属于泛型类,哪些属于非泛型类。。。根据经验,这可能是一个棘手的平衡行为。希望能有相当数量的来回 您似乎混淆了类型参数和继承。这应该起作用:
class Widget<PType> where PType :new()
{
public PType parent = new PType();
}
class ParentType {}
class WidgetParent : Widget<ParentType>
{
public void Slap() {Console.WriteLine("Slap"); }
}
class WidgetChild : Widget<WidgetParent>
{
}
public static void RunSnippet()
{
WidgetChild wc = new WidgetChild();
wc.parent.Slap();
}
类小部件,其中PType:new()
{
public PType parent=new PType();
}
类父类型{}
WidgetParent类:小部件
{
public void Slap(){Console.WriteLine(“Slap”);}
}
WidgetChild类:小部件
{
}
公共静态void RunSnippet()
{
WidgetChild wc=新的WidgetChild();
wc.parent.Slap();
}
使用接口:
interface IContainerWidget { }
class Widget
{
private IContainerWidget Container;
}
class ContainerWidget : Widget, IContainerWidget
{
}
这是我组织这件事的方法
public interface IWidget
{
void Behave();
IWidget Parent { get; }
}
public class AWidget : IWidget
{
IWidget IWidget.Parent { get { return this.Parent; } }
void IWidget.Behave() { this.Slap(); }
public BWidget Parent { get; set; }
public void Slap() { Console.WriteLine("AWidget is slapped!"); }
}
public class BWidget : IWidget
{
IWidget IWidget.Parent { get { return this.Parent; } }
void IWidget.Behave() { this.Pay(); }
public AWidget Parent { get; set; }
public void Pay() { Console.WriteLine("BWidget is paid!"); }
}
public class WidgetTester
{
public void AWidgetTestThroughIWidget()
{
IWidget myWidget = new AWidget() { Parent = new BWidget() };
myWidget.Behave();
myWidget.Parent.Behave();
}
public void AWidgetTest()
{
AWidget myWidget = new AWidget() { Parent = new BWidget() };
myWidget.Slap();
myWidget.Parent.Pay();
}
public void BWidgetTestThroughIWidget()
{
IWidget myOtherWidget = new BWidget() { Parent = new AWidget() };
myOtherWidget.Behave();
myOtherWidget.Parent.Behave();
}
public void BWidgetTest()
{
BWidget myOtherWidget = new BWidget() { Parent = new AWidget() };
myOtherWidget.Pay();
myOtherWidget.Parent.Slap();
}
}
我有一个类似的问题,并对其进行了调整以适应这一点(希望如此) 主代码
public class Parent<T>
where T : Child<T>
{
public Parent() { }
public T Get()
{
return Activator.CreateInstance(typeof(T), new object[] { this }) as T;
}
}
public class Child<T>
where T : Child<T>
{
Parent<T> _parent;
public Parent<T> Parent { get { return _parent; } }
public Child(Parent<T> parent)
{
_parent = parent;
}
}
public class ItemCollection : Parent<Item>
{
}
public class Item : Child<Item>
{
public Item(Parent<Item> parent)
: base(parent)
{
}
}
谢谢你的努力,查克里特。我已经详细阐述了它的用法。我认为重点是将父类型也约束为某种小部件。@Jon:没错,父类型具有上述约束。
public interface IWidget
{
void Behave();
IWidget Parent { get; }
}
public class AWidget : IWidget
{
IWidget IWidget.Parent { get { return this.Parent; } }
void IWidget.Behave() { this.Slap(); }
public BWidget Parent { get; set; }
public void Slap() { Console.WriteLine("AWidget is slapped!"); }
}
public class BWidget : IWidget
{
IWidget IWidget.Parent { get { return this.Parent; } }
void IWidget.Behave() { this.Pay(); }
public AWidget Parent { get; set; }
public void Pay() { Console.WriteLine("BWidget is paid!"); }
}
public class WidgetTester
{
public void AWidgetTestThroughIWidget()
{
IWidget myWidget = new AWidget() { Parent = new BWidget() };
myWidget.Behave();
myWidget.Parent.Behave();
}
public void AWidgetTest()
{
AWidget myWidget = new AWidget() { Parent = new BWidget() };
myWidget.Slap();
myWidget.Parent.Pay();
}
public void BWidgetTestThroughIWidget()
{
IWidget myOtherWidget = new BWidget() { Parent = new AWidget() };
myOtherWidget.Behave();
myOtherWidget.Parent.Behave();
}
public void BWidgetTest()
{
BWidget myOtherWidget = new BWidget() { Parent = new AWidget() };
myOtherWidget.Pay();
myOtherWidget.Parent.Slap();
}
}
public class Parent<T>
where T : Child<T>
{
public Parent() { }
public T Get()
{
return Activator.CreateInstance(typeof(T), new object[] { this }) as T;
}
}
public class Child<T>
where T : Child<T>
{
Parent<T> _parent;
public Parent<T> Parent { get { return _parent; } }
public Child(Parent<T> parent)
{
_parent = parent;
}
}
public class ItemCollection : Parent<Item>
{
}
public class Item : Child<Item>
{
public Item(Parent<Item> parent)
: base(parent)
{
}
}
ItemCollection col = new ItemCollection();
Item item = col.Get();
item.Parent.Slap();