如何创建传递给泛型方法

时间:2018-03-24 00:36:42

标签: c# generics

我已经尝试过多次从所谓的重复问题中插入代码,并且永远无法使其工作。来自其他问题/答案的代码:

(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种不同类型之一的项集合。我需要创建相应类型的对象并将它们添加到集合中。 EX:如果该方法通过<type A>的牌组,那么我需要创建一张卡片放入其中。

如果这不是通用的,那么代码行将如下所示:

FearCard fc = new FearCard(i, front, back);

诀窍是我需要创建的项目可能不是FearCard。它可能是BlightCard或其他几种类型。所以我只需要用自己的“通用友好”版本替换这行代码。

注意:FearCardBlightCard等类型都来自公共抽象类Card

1 个答案:

答案 0 :(得分:1)

假设您的所有 var arr = [{ "ID": "this THE ID", "NAME": "this THE NAME", "AGE": "thiS THE AGE" }, { "ID": "that ID", "NAME": "that THE NAME", "AGE": "that THE AGE" }] const result = arr.map(({ID,NAME,AGE}) => [ID,NAME,AGE]); console.log(result)子类型都有公共参数化构造函数,这些构造函数采用与Cardifront对应的三个参数,那么您可以使用Activator.CreateInstance(typeof(T), params Object[])构建卡的实例,其中backT项类型。

举一个具体的例子,假设您的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; } } 类型层次结构中使用chaining of constructors。派生类型不会自动从基类型继承参数化构造函数,因此必须为从Card派生的每个类创建公共参数化构造函数,并使用显式调用基类构造函数的一致签名。

  • 考虑使用工厂模式替换Card静态方法来创建卡片。一些可以帮助您入门的参考资料:

  • 在我的工作示例中,我对构造函数参数CardExtensions.CreateCard()ifront的类型做了一些假设,这些假设未在您的问题中显示。特定类型无关紧要,但它们需要在back类层次结构中相同类型。只要该假设是正确的,您可以更改它们以匹配您的实际类型。

示例工作.Net fiddle