Strongly typed object from string type name (C #)

if you look at the following code, you (hopefully) see that I'm trying to archive. Basically this code does:

  • Query for common storage items (they save their type as a string)
  • If the item is a subclass of SearchCriteria, create the correct instance
  • Add an instance to the list (SearchCriteria - superclass)

Not very elegant, of course, is the case of the pseudo switch, which I will have to update for all the different criteria that I create.

So my question is, is there a “general” way to create an instance that is strongly typed using a string as the “source” for the type.

I know that I can use Reflection to create an instance, but it is an object of type, so I could not add it to the list. Oh, just got an idea ... Create an object using reflection, add it to the supertype (SearchCrit), add it to the list. The real type should still be the "correct subtype", I hope ...

Let's try it and update the message with the results. Any better ideas?

Chris

private IList<SearchCriteria> _searchCriteriaAll; public IList<SearchCriteria> SearchCriteriaAll { get { if (_searchCriteriaAll == null) { _searchCriteriaAll = new List<SearchCriteria>(); var tN = typeof (SearchCriteria).ToString(); foreach (var o in DataStorage.LinkedObjects) { if (tN.StartsWith(o.TypeName)) { if (o.TypeName == typeof(StringSearchCriteria).ToString()) _searchCriteriaAll.Add(new StringSearchCriteria(o)); } } } return _searchCriteriaAll; } } 

EDIT:

Thanks for the tips, the "right" path will definitely be a factory pattern. I will look at that. At the moment I use this hack because the subclasses are so small, I do not want a factory for each of them .. (and this place is currently the only one with such a "bizarre" function)

  private IList<SearchCriteria> _searchCriteriaAll; public IList<SearchCriteria> SearchCriteriaAll { get { if (_searchCriteriaAll == null) { _searchCriteriaAll = new List<SearchCriteria>(); var tN = typeof (SearchCriteria).ToString(); foreach (var o in DataStorage.LinkedObjects) { if (tN.StartsWith(o.TypeName)) { var newO = Activator.CreateInstance(typeof(SearchCriteria).Assembly.FullName, o.TypeName); var newCrit = newO.Unwrap() as SearchCriteria; newCrit.DataStorage = o; _searchCriteriaAll.Add(newCrit); } } } return _searchCriteriaAll; } } 
+4
source share
3 answers

Generics and thinking do not make good friends. A simpler approach is to use a universal list interface:

 _searchCriteriaAll = new List<SearchCriteria>(); IList list = (IList) _searchCriteriaAll; ... Type type = typeof(SearchCriteria).Assembly.GetType(o.TypeName); list.Add(Activator.CreateInstance(type)); 

(where o.TypeName contains namespace information, but does not have to be grouped)

It is still safe at runtime (it will exit at runtime if it is not) and still configures the same list.

Note also that we simply look inside Assembly directly through Assembly.GetType() .

+3
source

I would say that you are looking for Factory Method Template .

Here's a C # example here - the first link describes the template better, the second is the right language for you.

0
source

I don’t quite understand what you are trying to achieve, but you can create a Type from a string as follows:

 var t = Type.GetType(typeName); 

If you want to check if it is the correct subtype, you can use the IsAssignableFrom method.

0
source

Source: https://habr.com/ru/post/1299829/


All Articles