C# 在列表中的泛型函数中使用子类型<;家长>;对象
我的问题与我希望在泛型方法中使用子类型的方法类似,只是不调用该方法。例如:C# 在列表中的泛型函数中使用子类型<;家长>;对象,c#,generics,C#,Generics,我的问题与我希望在泛型方法中使用子类型的方法类似,只是不调用该方法。例如: class Parent { } class Child1 : Parent { } class Child2 : Parent { } // could be other child classes, unknown to the Process class class Process { public Process() { List<Parent> L = new Li
class Parent { }
class Child1 : Parent { }
class Child2 : Parent { }
// could be other child classes, unknown to the Process class
class Process
{
public Process()
{
List<Parent> L = new List<Parent>();
Child1 C1 = new Child1();
Child2 C2 = new Child2();
L.Add(C1);
L.Add(C2);
foreach(Parent P in L)
{
DoSomething(P);
}
}
public void DoSomething<TypeP>(TypeP P)
{
// P is 'Child1', 'Child2' or potentially something else
// TypeP is 'Parent'
//TypeP = P.GetType(); //doesnt work
//DoSomethingElse<P.GetType()>(); //doesnt work
DoSomethingElse<TypeP>();
}
public void DoSomethingElse<T>()
{
// T is 'Parent'
T R = Activator.CreateInstance<T>(); // want R to be 'Child1' or 'Child2'
}
}
类父{}
类Child1:父{}
类Child2:父{}
//可能是流程类未知的其他子类
类进程
{
公共程序()
{
列表L=新列表();
Child1 C1=新的Child1();
Child2 C2=新的Child2();
L.加入(C1);
L.Add(C2);
foreach(父P在L中)
{
剂量测定法(P);
}
}
公共无效剂量测定(类型P)
{
//P是“Child1”、“Child2”或其他可能的词
//TypeP是“父级”
//TypeP=P.GetType();//不起作用
//DoSomethingElse();//不起作用
DoSomethingElse();
}
公共无效DoSomethingElse()
{
//T是“家长”
T R=Activator.CreateInstance();//希望R为'Child1'或'Child2'
}
}
我希望使用C1或C2类型而不是“父”类型来调用DoSomethingElse。我已经来过几次了,但找不到一个办法让它发挥作用。我觉得这应该是微不足道的,因为P是正确的类型
编辑:
DoSomethingElse之所以是泛型的,是因为可以从父类派生任意数量的子类。我以Child1和Child2为例,但实际上可能还有很多,因此DoSomethingElse中的switch语句不可行,因为派生类的数量未知。上面的代码有几处错误。 泛型只适用于编译时已知的类型。在这里,我们将所有值向上转换为基类:
// L is a List<Parent>
L.Add(C1);
L.Add(C2);
现在我们可以使用带有约束的泛型,TChild
应该从Parent
派生:
public void DoSomething<TChild>(TChild P) where TChild : Parent
{
...
DoSomethingElse(P);
}
以下是您可以使用is关键字检查类型:
public void DoSomething<TypeP>(TypeP P)
{
if (P is Child1)
{
}
else if(P is Child2)
{
}
}
public void DoSomething(类型P)
{
if(P是Child1)
{
}
else if(P为Child2)
{
}
}
这里有两个选项:
public void DoSomething<TypeP>(TypeP P)
{
P.DoSomethingElse(); // this is virtual method to be overwritten by children types
}
public void DoSomething(类型P)
{
P.DoSomethingElse();//这是要被子类型覆盖的虚拟方法
}
在您的特定情况下,您希望调用
Activator.CreatInstance()
,但还有一种选择。有一个方法[Activator.CreatInstance(Type)][1]
你可以通过稍微改变你的剂量测定方法来使用它
public void DoSomethingElse(Parent p)
{
var R = Activator.CreateInstance(p.GetType());
}
当然,在不知道你在用它做什么的情况下,我不知道这是否一定有帮助。您可能仍然需要对R类型使用某种switch语句,然后才能使用这个新对象。但是,如果从这一点开始,您可以将
R
视为类型Parent
,那么这应该会对您有所帮助。使用dynamics或cast-as并检查是否为null?我觉得应该有人指出,这感觉有点错误,如果DoSomethingElse
的类型参数是什么那么重要,也许这三种类型实际上不应该按它们的方式排列?看,它们不起作用的原因是因为泛型是编译时的事情-编译器决定如何调用泛型方法。这就是为什么在运行时尝试设置TypeP的类型是行不通的。由于您只知道运行时的类型,因此您的选项(假设您需要列表L
作为list
保留)几乎都是在运行时执行类型检查…@Leszek Repie将“DoSomething(P);”替换为“DoSomething(P作为动态);”似乎有效,尽管我不知道为什么在这个阶段子类的数量未知(因此泛型)。我已经做了一个编辑,希望能让它更清楚。@xareth更新了我的答案子类的数量未知(因此泛型)
-这对我来说毫无意义,“数字未知”和“因此泛型”之间有什么联系?@Maarten也许我的逻辑不正确,但该方法是泛型的,因此它可以处理任何类型的“parent:child”类(只是键入使我认为它不正确)。使用泛型类型的真正原因是最终将其传递给Activator.CreateInstance(),谢谢Fabjan。我已经解决了它。结果我需要指定一个额外的泛型类型。因此“DoSomethingElse()”变成了“DoSomethingElse()”。一旦我更改了答案,您的答案最终就起作用了。
public void DoSomething<TypeP>(TypeP P)
{
if (P is Child1)
{
}
else if(P is Child2)
{
}
}
public void DoSomething<TypeP>(TypeP P)
{
P.DoSomethingElse(); // this is virtual method to be overwritten by children types
}
public void DoSomethingElse(Parent p)
{
var R = Activator.CreateInstance(p.GetType());
}