[英]How to create a object of the same (user-defined)type passed into a generic method
我已经尝试过多次从所谓的重复问题中插入代码,但始终无法正常工作。 来自其他问题/答案的代码:
(T)Activator.CreateInstance(typeof(T), new object[] { weight });
再次,如下所述/以前:我已经尝试过其他问题的解决方案,但对我却不起作用。 也许有人可以尝试向我解释如何在我的项目中使用其他答案的代码,而不是不真正阅读我的帖子并将其标记为重复?
我在尝试使用通用扩展方法时遇到问题。 我的伪伪代码:
internal static class MyExtensions
{
public static void CreateDeck<T>(this ObservableCollection<T> deck)
{
...
Card card = null;
if (deck.GetType() == typeof(FearCard))
{
card = new FearCard(i, front, back);
}
else if (deck.GetType() == typeof(EventCard))
{
card = new EventCard(i, front, back);
}
else if (deck.GetType() == typeof(InvaderCard))
{
card = new InvaderCard(i, front, back);
}
else if (deck.GetType() == typeof(BlightCard))
{
card = new BlightCard(i, front, back);
}
deck.Add(card);
...
}
}
我的其余代码(未包括在内)工作正常,但是需要简化此块。 我知道这不是一个好代码,我只是将其写出来,以便某人可以(希望)看到我实际上要完成的工作,并可以向我展示实现此目标的正确方法。 我尝试了Activator.CreateInstance
但似乎无法使其正常工作。
这是我最近尝试过的实际代码:
var temp = dType;
Type[] typeArgs = { dType };
var temp2 = temp.MakeGenericType(typeArgs);
var card = Activator.CreateInstance(temp2);
deck.Add(card);
和:
dynamic card = new dynamic(i, front, back);
deck.Add(card);
和:
T card = (T)Activator.CreateInstance(typeof(T), new object[] { i, front, back });
deck.Add(card);
以及以上的其他版本/尝试。
但是它们都不起作用。 =(
传递给该方法的“ deck”对象将是4种不同类型之一的项目的集合。 我需要创建相应类型的对象并将其添加到集合中。 例:如果该方法通过了<type A>
牌组,那么我需要创建一张卡片放入其中。
如果这不是通用的,则代码行将如下所示:
FearCard fc = new FearCard(i, front, back);
诀窍是我需要创建的物品可能不是FearCard
。 它可能是BlightCard
或其他几种类型。 因此,我只需要用“通用友好”版本本身来替换这一行代码。
注意: FearCard
, BlightCard
等类型均源自公共抽象类Card
。
假设所有Card
子类型都有公共参数化的构造函数,这些构造函数采用与i
, front
和back
对应的三个参数,则可以使用Activator.CreateInstance(typeof(T), params Object[])
来构造卡的实例,其中T
为ObservableCollection<T>
项类型。
举一个具体的例子,假设您的Card
类型层次结构如下所示:
public abstract class Card
{
public int Index { get; private set; }
public string Front { get; private set; }
public string Back { get; private set; }
public Card(int index, string front, string back)
{
this.Index = index;
this.Front = front;
this.Back = back;
}
}
public class FearCard : Card
{
public FearCard(int index, string front, string back) : base(index, front, back) { }
}
public class EventCard : Card
{
public EventCard(int index, string front, string back) : base(index, front, back) { }
}
public class InvaderCard : Card
{
public InvaderCard(int index, string front, string back) : base(index, front, back) { }
}
public class BlightCard : Card
{
public BlightCard(int index, string front, string back) : base(index, front, back) { }
}
然后,可以使用以下两种方法构造Card
的具体实例并将其添加到ObservableCollection<T>
:
internal static class CardExtensions
{
public static T CreateCard<T>(int index, string front, string back) where T : Card
{
return (T)Activator.CreateInstance(typeof(T), index, front, back);
}
}
internal static class MyExtensions
{
public static T CreateDeck<T>(this ObservableCollection<T> deck, int index, string front, string back) where T : Card
{
if (deck == null)
throw new ArgumentNullException();
var card = CardExtensions.CreateCard<T>(index, front, back);
deck.Add(card);
return card;
}
}
笔记:
注意在Card
类型层次结构中使用构造函数链 。 派生类型不会自动从基类型继承参数化的构造函数,因此必须为每个从Card
派生的类创建公共参数化的构造函数,这些类具有显式调用基类构造函数的一致签名。
考虑使用工厂模式替换CardExtensions.CreateCard()
静态方法来创建卡。 一些参考,可以帮助您入门:
在我的工作示例中,我对构造函数参数i
, front
和back
的类型进行了一些假设,这些问题未在您的问题中显示。 特定的类型无关紧要,但是在整个Card
类层次结构中,它们必须是相同的类型 。 只要该假设正确,您就可以更改它们以匹配您的实际类型。
样本工作.Net提琴 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.