我有课程 MyWord 以及许多其他课程,例如继承自MyWord的 Noun,Idiom 等。
我将这些对象存储在一个列表中:
List<MyWord> Dictionary;
当我将新元素添加到列表时,我这样做:
var myWord = new MyWord(id, word, definition,type,DateTime.Now.ToShortDateString());
Dictionary.Add(myWord);
如你所见,我把对象 MyWord 放在那里。我希望能够创建例如 Noun 对象并将其放入列表中,如下所示:
var myWord = new Noun(id, word, definition, type, DateTime.Now.ToShortDateString());
Dictionary.Add(myWord);
type 参数是一个字符串,例如“noun”。我使用此方法根据此字符串获取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结构来创建检查 type 变量的不同对象,但这不是一个优雅的解决方案。有更好的想法吗?
答案 0 :(得分:3)
您可以使用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>>
,您可以在其中查找单词类型并获得一个函数适用于word
和definition
值?
wordFactories["noun"](word, definition);
另一个替代方法是使用Nuget中的Impromptu.Interface
,它可以包装接口中的任何动态对象,并使其行为就像那样。在我的.NET自然语言引擎中,我用它从数据库中取出一个单词,然后将其包装起来,比如INoun
,IPluralNoun
,{{1等等。
答案 1 :(得分:1)
如果我们看一下,你尝试做的事情仍然是不可能的:
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
关键字创建实例慢。