c#将对象强制转换为存储在字符串变量中的另一种类型

本文关键字:变量 字符串 类型 另一种 存储 对象 转换 | 更新日期: 2023-09-27 18:19:01

我有类MyWord和许多其他类,如名词,成语等,从MyWord继承。

我将这些对象存储在一个列表中:

List<MyWord> Dictionary;

当我向列表中添加新元素时,我这样做:

var myWord = new MyWord(id, word, definition,type,DateTime.Now.ToShortDateString());
Dictionary.Add(myWord);

如你所见,我把对象MyWord放在那里。我希望能够创建例如名词对象,并放入列表中,像这样:

var myWord = new Noun(id, word, definition, type, DateTime.Now.ToShortDateString());
Dictionary.Add(myWord);

type参数为字符串,例如"名词"。我使用这个方法来获取基于这个字符串的Type:

    private Type GetFullType(string myType)
    {
        //Returns list of all types that inherit from MyWord class
        var supportedTypes = (AppDomain.CurrentDomain.GetAssemblies()
                            .SelectMany(assembly => assembly.GetTypes())
                            .Where(type => type.IsSubclassOf(typeof(MyWord)))).Select(x => x.FullName).ToList();
        return Type.GetType(supportedTypes.Find(x => x.Contains_SkipWhiteSpacesIgnoreCase(myType)));
    }

现在我不知道如何使用GetFullType()返回值转换MyWord名词。这样的:

        Type wordType = GetFullType(type);
        var myWord = new MyWord(id, word, definition, type, DateTime.Now.ToShortDateString());
        Dictionary.Add((wordType)myWord);

我希望我解释清楚了。

注意,我可以使用If…Else结构来创建不同的对象,检查类型变量,但这不是一个优雅的解决方案。有更好的主意吗?

c#将对象强制转换为存储在字符串变量中的另一种类型

您可以使用Activator.CreateInstance创建类型的实例。见https://msdn.microsoft.com/en-us/library/wccyzw83 (v = vs.110) . aspx

var myword = Activator.CreateInstance(wordType);

然后你可以使用反射设置它的属性,或者通过将它强制转换为基类MyWord

或者你可以在wordType上使用反射来找到它的构造函数并调用它。

但真的,有很多词类型,它不是更容易(和整个更快)维护一个Dictionary<string,Func<string, string, WordType>>,你可以查找一个词的类型,并得到一个函数,使你从它的worddefinition值?

wordFactories["noun"](word, definition);

另一种选择是使用Nuget中的Impromptu.Interface,它可以将任何动态对象包装在接口中,并使其表现得像那样。在我的。net自然语言引擎中,我用它从数据库中获取一个单词然后将其包装成,比如,INoun IPluralNoun IMammal等等

你想要做的仍然是不可能的,因为如果我们看一下这个:

Type wordType = GetFullType(type);
var myWord = new MyWord(id, word, definition, type, DateTime.Now.ToShortDateString());
Dictionary.Add((wordType)myWord);

您创建了MyWord的实例,它不能在Noun或类似的东西中强制转换,因为它没有类型。您可以使用的是Activate.CreateInstance。看看这个:Activator。调用CreateInstance

这个静态方法还允许接受一个参数列表,这些参数将自动传递给构造函数。但请确保,这使用反射,并且总是比使用new关键字创建实例要慢。