Pergunta

i've got a class filled with lists of subclasses:

public class ClassOfKb
{
    public List<Data> KbDatas {get;set;}
    public List<Product> KbProducts {get;set}
}

public class Data
{
    public Guid ID {get;set;}
    public byte[] data {get;set;}
    public string Name {get;set;}
}
public class Product
{
    public Guid ID {get;set;}
    public string Name {get;set;}
    public byte[] Image {get;set;}
}

i create an object:

ClassOfKb kb = new ClassOfKb

now i'd like to extract the string "Datas" from the sub-object kb.KbDatas, I tried:

string name = kb.KbDatas.GetType().BaseType.Name.Substring(2);

aswell as:

string name = kb.KbDatas.GetType().Name.Substring(2);

but nothing gave me what I need, is there any way to do this?

EDIT: to specify my question, the string I need is the name of the list, except the first two letters! KbDatas => Datas

EDIT2: i did a mistake, the list-names and class-names are different and i need the list-name

Foi útil?

Solução

You can use Type.GetGenericArguments to solve this

       ClassOfKb kb=new ClassOfKb();
      kb.KbData = new List<Data>();
      string nameOfData = Type.GetType(kb.KbData.ToString()).GetGenericArguments().Single().Name;

OUTPUT : nameOfData = Data

      kb.KbProduct = new List<Product>();
      string nameOfProduct = Type.GetType(kb.KbProduct.ToString()).GetGenericArguments().Single().Name;

OUTPUT : nameOfProduct = Product

Outras dicas

Since that's a collection it is likely that there are multiple Data objects in it, each with a name. You can use String.Join to concat them with a separator:

string names = string.Join(",", kb.KbData.Select(d => d.Name));

If there's just one object you don't get a comma at the end. If there's no object you get an empty string.

erm, since you have a List of Data there will be a sequence of Names.

IEnumerable<string> names = kb.KbData.Select(d => d.Name);

maybe you want just the first one?

string firstName = kb.KbData.First(d => d.Name);

Try this one

string name = kb.KbData[0].Name.Substring(2);

From the sounds of what you've written, you're looking to get the name of the type in the List instance KbData?

If so, I think this may be what you're looking for: https://stackoverflow.com/a/1043778/775479

If you are trying to get the name of the property. There are several methods for doing so.

Get the name of the generic argument from the property itself - If you know the name of the property.

ClassOfKb kb = new ClassOfKb()
   { KbData = new List<Data>(), KbProduct = new List<Product>() };
Console.WriteLine(kb.KbData.GetType().GetGenericArguments()[0].Name);

Get the name of the property from reflection, if you know the data type of the property.

System.Reflection.PropertyInfo pi = kb.GetType()
           .GetProperties()
           .FirstOrDefault(p=>p.PropertyType == typeof(List<Data>));
Console.WriteLine(pi.Name.Substring(2)); // ignoring the kb prefix

You can achieve this with reflection. This is example without any checks - just show the mechanism:

PropertyInfo propertyInfo = typeof(ClassOfKb).GetProperty("KbData");
Type propertyType = propertyInfo.PropertyType;
Type genericArgument = propertyType.GenericTypeArguments[0];
string name = genericArgument.Name;

Because property KbData is generic List<Data> you need ask for generic arguments of property type: propertyType.GenericTypeArguments[0] and you should test if the type is really generic by genericArgument.IsGenericType and check generic arguments count

If you need the property name than you can use Expression. The code below define function for extract name prom a property:

public string GetPropertyName<T>(Expression<Func<T>> property)
{
    return ((MemberExpression)property.Body).Member.Name;
}

This converts property to property name string:

GetPropertyName(()=>k.KbDatas).Substring(2)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top