Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check T generic type has property S (generic) in c#

class A

class A{
...
}

class B

 class B:A{
    ...
 }

class C

 class C:A{
    B[] bArray{get;set;}
 }

I would like to check if T has a property type of S , create instance of S and assignment to that propery :

public Initial<T,S>() where T,S : A{
   if(T.has(typeof(S))){
      S s=new S();
      T.s=s;
   }
}
like image 203
Mohammad Javad Avatar asked Feb 04 '16 09:02

Mohammad Javad


People also ask

How do you find a generic type?

Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.

Where is generic type constraint?

The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.

How do you know if an object is generic?

If you want to check if it's an instance of a generic type: return list. GetType().

Is it possible to inherit from generic type?

You can't inherit from a Generic type argument. C# is strictly typed language. All types and inheritance hierarchy must be known at compile time. . Net generics are way different from C++ templates.


2 Answers

The best and easiest thing to do is implement this functionality using an interface.

public interface IHasSome
{
    SomeType BArray {get;set;}
}

class C:A, IHasSome
{
    public SomeType BArray {get;set;}
}

Then you can cast the object in your generic method:

public T Initial<T,S>() where T : new() where S : SomeType, new()
{
    T t = new T();

    if (t is IHasSome)
    {
        ((IHasSome)t).BArray = new S();
    }

    return t;
}

If that doesn't fit, you can use reflection to go over the properties and check their types. Set the variable accordingly.

like image 126
Patrick Hofman Avatar answered Oct 06 '22 02:10

Patrick Hofman


I agree with @PatrickHofman that way is better, but if you want somethig more generic that creates a new instance for all properties of a type, you can do that using reflection:

public T InitializeProperties<T, TProperty>(T instance = null) 
    where T : class, new()
    where TProperty : new()
{
    if (instance == null)
        instance = new T();

    var propertyType = typeof(TProperty);
    var propertyInfos = typeof(T).GetProperties().Where(p => p.PropertyType == propertyType);

    foreach(var propInfo in propertyInfos)
        propInfo.SetValue(instance, new TProperty());

    return instance;
}

Then:

// Creates a new instance of "C" where all its properties of the "B" type will be also instantiated
var cClass = InitializeProperties<C, B>();

// Creates also a new instance for all "cClass properties" of the "AnotherType" type
cClass = InitializeProperties<C, AnotherType>(cClass);
like image 31
Alexandre Ribeiro Avatar answered Oct 06 '22 04:10

Alexandre Ribeiro