繁体   English   中英

如何创建传递给泛型方法的相同(用户定义)类型的对象

[英]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或其他几种类型。 因此,我只需要用“通用友好”版本本身来替换这一行代码。

注意: FearCardBlightCard等类型均源自公共抽象类Card

假设所有Card子类型都有公共参数化的构造函数,这些构造函数采用与ifrontback对应的三个参数,则可以使用Activator.CreateInstance(typeof(T), params Object[])来构造卡的实例,其中TObservableCollection<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()静态方法来创建卡。 一些参考,可以帮助您入门:

  • 在我的工作示例中,我对构造函数参数ifrontback的类型进行了一些假设,这些问题未在您的问题中显示。 特定的类型无关紧要,但是在整个Card类层次结构中,它们必须是相同的类型 只要该假设正确,您就可以更改它们以匹配您的实际类型。

样本工作.Net提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM