Can a generic class re-create itself with another type

T

tadmill

Is it possible for a class that accepts a generic type, to re-create
another instance of itself with a property type of the passed class?

ex.
public class SomeClass<T>
{
private PropertyInfo[] propInfos;
private Type objectType = typeof(T);

public SomeClass()
{
propInfos = objectType.GetProperties();
foreach (PropertyInfo pinn in propInfos)
{
if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
{
//Can another SomeClass<> be created here with the property's
type?
}
}
}
}

I have attacked this 10 different ways and haven't come up with
anything that works. That may be because it can't be done; has anyone
else attempted this successfully?

TIA for any help,
Terry
 
J

Jon Skeet [C# MVP]

On Jun 4, 5:25 pm, (e-mail address removed) wrote:

I have attacked this 10 different ways and haven't come up with
anything that works. That may be because it can't be done; has anyone
else attempted this successfully?

You can certainly create closed types (and then instances of them)
with reflection. Reflection with generic types isn't much fun, but
it's definitely doable. If you could provide a short but complete
program which attempts to *use* your SomeClass<T> (and verifies that
it behaves correctly) I'd be happy to have a go at implementing it.
(Unit tests would be even better than a short but complete program, of
course).

Jon
 
T

Thomas W. Brown

Is it possible for a class that accepts a generic type, to re-create
another instance of itself with a property type of the passed class?

ex.
public class SomeClass<T>
{
private PropertyInfo[] propInfos;
private Type objectType = typeof(T);

public SomeClass()
{
propInfos = objectType.GetProperties();
foreach (PropertyInfo pinn in propInfos)
{
if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
{
//Can another SomeClass<> be created here with the property's
type?
}
}
}
}

I have attacked this 10 different ways and haven't come up with
anything that works. That may be because it can't be done; has anyone
else attempted this successfully?

TIA for any help,
Terry

I could be wrong, but if a given type, say Foo, has a property that is a
generic declaration of SomeClass, then Foo itself would have to be generic as
well, wouldn't it?

e.g.:
class Foo<T>
{
...
public SomeClass<T> m_InnerSomeClass;
...
}

So, if you now instantiate a SomeClass object with Foo as the type:

SomeClass<Foo> aFooSomeClass = new SomeClass<Foo>();

Then the type is already determined. Actually instantiating this object
could potential run into issues because of the recursive nature of the type.

The only other approach would be for Foo to have already locked in the type:

class Foo
{
...
public SomeClass<int> m_IntSomeClass;
...
}

And now there is no need to worry about the inner property when creating an
object of type SomeClass<Foo>.

Again, having not gotten eyeball deep in use of Generics for tricky
covariant and contravariant use cases, I could be missing something. Plus,
I'm not sure I'm really understanding your situation -- a more concrete
example of a pair of such classes with a description of what you would *want*
to happen would help.

Regards,
-- TB
 
T

tadmill

The only other approach would be for Foo to have already locked in the type:

   class Foo
   {
      ...
      public SomeClass<int> m_IntSomeClass;
      ...
   }


- Show quoted text -

Thomas,

That's basically what I've got, a property of SomeClass<>, only the
type is another class:

class Foo
{
...
public SomeClass<OtherClass> TheOtherOne {}
...
}

And I haven't gotten too deep into generics either, my experience has
mostly been writing classes that inherit BindingList<T> for grid data,
which I've done with relative success, but that's about it.
 
B

Ben Voigt [C++ MVP]

Is it possible for a class that accepts a generic type, to re-create
another instance of itself with a property type of the passed class?

ex.
public class SomeClass<T>
{
private PropertyInfo[] propInfos;
private Type objectType = typeof(T);

public SomeClass()
{
propInfos = objectType.GetProperties();
foreach (PropertyInfo pinn in propInfos)
{
if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
{
//Can another SomeClass<> be created here with the property's
type?
}
}
}
}

Do you just want an object of the same type? Use the Activator class.

Do you need to somehow combine the type arguments from reflection with a
generic type, i.e. you found a SomeClass<T> so you now need to create a
List<T>?

Type ListT =
typeof(List).MakeGenericType(pinn.PropertyType.GetGenericArguments());

and then use Activator
 
T

tadmill

Is it possible for a class that accepts a generic type, to re-create
another instance of itself with a property type of the passed class?
ex.
public class SomeClass<T>
{
 private PropertyInfo[] propInfos;
 private Type objectType = typeof(T);
 public SomeClass()
 {
  propInfos = objectType.GetProperties();
  foreach (PropertyInfo pinn in propInfos)
  {
    if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
    {
      //Can another SomeClass<> be created here with the property's
type?
    }
  }
 }
}

Do you just want an object of the same type?  Use the Activator class.

Do you need to somehow combine the type arguments from reflection with a
generic type, i.e. you found a SomeClass<T> so you now need to create a
List<T>?

Type ListT =
typeof(List).MakeGenericType(pinn.PropertyType.GetGenericArguments());

and then use Activator- Hide quoted text -

- Show quoted text -

That actually looks like it could do the trick! I researched it more
in the MSDN help, I was wondering- could a method be referenced from
an object created this way? Maybe through a delegate, or MethodInfo?
I haven't tried coding anything yet, but it's something that came to
mind as I was mulling over your suggestion.

Thanks again for the help, that could be a real life saver, I just
haven't had a chance to plug it in yet,

Terry
 
B

Ben Voigt [C++ MVP]

Is it possible for a class that accepts a generic type, to re-create
another instance of itself with a property type of the passed class?
ex.
public class SomeClass<T>
{
private PropertyInfo[] propInfos;
private Type objectType = typeof(T);
public SomeClass()
{
propInfos = objectType.GetProperties();
foreach (PropertyInfo pinn in propInfos)
{
if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
{
//Can another SomeClass<> be created here with the property's
type?
}
}
}
}

Do you just want an object of the same type? Use the Activator class.

Do you need to somehow combine the type arguments from reflection with a
generic type, i.e. you found a SomeClass<T> so you now need to create a
List<T>?

Type ListT =
typeof(List).MakeGenericType(pinn.PropertyType.GetGenericArguments());

and then use Activator- Hide quoted text -

- Show quoted text -

That actually looks like it could do the trick! I researched it more
in the MSDN help, I was wondering- could a method be referenced from
an object created this way? Maybe through a delegate, or MethodInfo?
I haven't tried coding anything yet, but it's something that came to
mind as I was mulling over your suggestion.

Sure can. The best case (in terms of performance and code needed to get it
done) is when the dynamically-created object implements a known interface.
For example, List<T> implements IEnumerable no matter what T is, so you
could cast the resulting object to IEnumerable.

Otherwise, if one of the member functions is compatible with a known
delegate type, you can hook it up and call through the delegate. Creating
the delegate will be slow, the call will be very fast though, so if you call
repeatedly you will amortize the initial cost.

Calling through reflection (MethodInfo.Invoke) is the most flexible but by
far the slowest.
 
T

tadmill

(e-mail address removed) wrote:
Is it possible for a class that accepts a generic type, to re-create
another instance of itself with a property type of the passed class?
ex.
public class SomeClass<T>
{
private PropertyInfo[] propInfos;
private Type objectType = typeof(T);
public SomeClass()
{
propInfos = objectType.GetProperties();
foreach (PropertyInfo pinn in propInfos)
{
if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
{
//Can another SomeClass<> be created here with the property's
type?
}
}
}
}
Do you just want an object of the same type? Use the Activator class.
Do you need to somehow combine the type arguments from reflection with a
generic type, i.e. you found a SomeClass<T> so you now need to create a
List<T>?
Type ListT =
typeof(List).MakeGenericType(pinn.PropertyType.GetGenericArguments());
and then use Activator- Hide quoted text -
- Show quoted text -
That actually looks like it could do the trick!  I researched it more
in the MSDN help, I was wondering- could a method be referenced from
an object created this way?  Maybe through a delegate, or MethodInfo?
I haven't tried coding anything yet, but it's something that came to
mind as I was mulling over your suggestion.

Sure can.  The best case (in terms of performance and code needed to getit
done) is when the dynamically-created object implements a known interface.
For example, List<T> implements IEnumerable no matter what T is, so you
could cast the resulting object to IEnumerable.

Otherwise, if one of the member functions is compatible with a known
delegate type, you can hook it up and call through the delegate.  Creating
the delegate will be slow, the call will be very fast though, so if you call
repeatedly you will amortize the initial cost.

Calling through reflection (MethodInfo.Invoke) is the most flexible but by
far the slowest.




Thanks again for the help, that could be a real life saver, I just
haven't had a chance to plug it in yet,
Terry- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Ben,
This is essentially my first time of creating a custom interface, and
that worked perfectly! It's a sweet solution to be able to apply the
same functionality to completely different objects. I had it stuck in
my head that I had to use Reflection, when after all that a simple
interface with a few defined functions worked much better.

Thanks to everyone again for all the help, it has been a real life
saver.
 
A

Ankur

Is it possible for aclassthat accepts agenerictype, to re-create
another instance of itself with a property type of the passedclass?

ex.
publicclassSomeClass<T>
{
  private PropertyInfo[] propInfos;
  private Type objectType = typeof(T);

  public SomeClass()
  {
   propInfos = objectType.GetProperties();
   foreach (PropertyInfo pinn in propInfos)
   {
     if (pinn.PropertyType.IsGenericType &&
pinn.PropertyType.GetGenericTypeDefinition() == typeof(SomeClass<>))
     {
       //Can another SomeClass<> be created here with the property's
type?
     }
   }
  }

}

I have attacked this 10 different ways and haven't come up with
anything that works.  That may be because it can't be done; has anyone
else attempted this successfully?

TIA for any help,
Terry

SELECT distinct SysObjects.[Name] as TableName, SysColumns.
[Name] as ColumnName,
SysTypes.[Name] As DataType,
SysColumns.[Length] As Length FROM SysObjects INNER JOIN
SysColumns ON SysObjects.[Id] = SysColumns.[Id]
INNER JOIN SysTypes ON SysTypes.[xtype] = SysColumns.
[xtype]
WHERE SysTypes.[Name]='image' and SysObjects.[type] = 'U'
ORDER BY SysObjects.[Name]


SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES WHERE
ROUTINE_DEFINITION LIKE '%aup_Photo%' AND ROUTINE_TYPE='PROCEDURE'
ORDER BY ROUTINE_NAME
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top