Anonymous Method/Properties etc with <T>

  • Thread starter Thread starter Rene
  • Start date Start date
R

Rene

We all know that we can't call custom methods or properties form generic
type parameters (<T>) by default because the compiler will complain about
his. For example, the following won't normally compile:

T.MyCustomMethod()

The compiler will tell me that it's not sure that the generic type
parameters (<T>) will contain such method and will requires me to constrain
the generic type parameters.

My question is. Why doesn't the compiler allow for things such as anonymous
methods or properties when using generic type parameters (<T>)? Why won't
the compiler assume that such method with such return type is declared on
<T> and then only complain when the type parameter *is* replace with the
actual object it was meant to be replace with? Why the absolute necessity to
constrain the type parameter?

Thanks.
 
Rene,

The big reason is because of the way that generics are handled at run
time. The CLR is actually aware of them as generics. In C++ templates,
which is the base for your desired behavior, it can be verified at compile
time if the methods exist or not, and then act appropriately if they don't.

With Generics, that's not possible. The reason is that your
parameterized type might be used by another library/exe/whatever and insert
it's own type into the type parameter. You can't know this at compile time
as a result, since your type theoretically can be used anywhere else.

Hope this helps.
 
Aaah, now I remember reading something about the compile vs runtime issue,
should have paid more attention to that book chapter.

I guess it would be nice to have an attribute that could be place on the
method call from <T> where you could easily instruct the compiler to create
code for you that reflects on the type to make the call so that we don't
have the problem (cheese solution but..), also I would think that compiler
should be able to tell if the class or method with the generic type
parameter is marked as internal and if this is the case, then it should be
able to do this check at compile time right?

Thanks.


Nicholas Paldino said:
Rene,

The big reason is because of the way that generics are handled at run
time. The CLR is actually aware of them as generics. In C++ templates,
which is the base for your desired behavior, it can be verified at compile
time if the methods exist or not, and then act appropriately if they
don't.

With Generics, that's not possible. The reason is that your
parameterized type might be used by another library/exe/whatever and
insert it's own type into the type parameter. You can't know this at
compile time as a result, since your type theoretically can be used
anywhere else.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Rene said:
We all know that we can't call custom methods or properties form generic
type parameters (<T>) by default because the compiler will complain about
his. For example, the following won't normally compile:

T.MyCustomMethod()

The compiler will tell me that it's not sure that the generic type
parameters (<T>) will contain such method and will requires me to
constrain the generic type parameters.

My question is. Why doesn't the compiler allow for things such as
anonymous methods or properties when using generic type parameters (<T>)?
Why won't the compiler assume that such method with such return type is
declared on <T> and then only complain when the type parameter *is*
replace with the actual object it was meant to be replace with? Why the
absolute necessity to constrain the type parameter?

Thanks.
 
Rene said:
Aaah, now I remember reading something about the compile vs runtime issue,
should have paid more attention to that book chapter.

I guess it would be nice to have an attribute that could be place on the
method call from <T> where you could easily instruct the compiler to create
code for you that reflects on the type to make the call so that we don't
have the problem (cheese solution but..), also I would think that compiler
should be able to tell if the class or method with the generic type
parameter is marked as internal and if this is the case, then it should be
able to do this check at compile time right?

You can do that very easily by making the actual class of T implement
an interface (eg IMyInterface) and then constraint T using
"where T : IMyInterface" on the declaration.

However, if you're really wanting C# to be a dynamically typed
language, you're out of luck.
 
You can do that very easily by making the actual class of T implement
an interface (eg IMyInterface) and then constraint T using
"where T : IMyInterface" on the declaration.
Yes, I was aware of that, I was just wondering the reason for needing to do
that whish was explained to me already.

I still think that the compiler should be smart enough not requiring any
kind of constrains on the generic type parameter if the class or method
declaring the type parameter (<T>) is marked as private or internal since
the scope of these calls are low enough that the compiler will know for sure
before runtime what will replace the <T> parameter.

Remember that you don't always have to distribute code via assemblies. You
can use SourceSafe for example to share raw code allowing you to use the
code in other projects and be able to keep the scopes as internal. Some
benefits of the compiler handling the scenario like this is that this way
you wont have the nightmare when implementing == <> etc when using generics.
 
Rene said:
Yes, I was aware of that, I was just wondering the reason for needing to do
that whish was explained to me already.

I still think that the compiler should be smart enough not requiring any
kind of constrains on the generic type parameter if the class or method
declaring the type parameter (<T>) is marked as private or internal since
the scope of these calls are low enough that the compiler will know for sure
before runtime what will replace the <T> parameter.

I dare say it *could* do that - but personally I don't like the idea.
In my view you should be able to tell whether or not a type's source
code (potentially across multiple files in the case of partial types)
is valid or not solely by looking at it and the types it uses. Randomly
calling methods which may or may not actually be the ones you want
(String.Join and Thread.Join do radically different things, despite
having the same name, for instance) isn't my idea of a good situation
for readable, maintainable code. (And that's not to mention the spec
and compiler changes, which would be horredous.)
Remember that you don't always have to distribute code via assemblies. You
can use SourceSafe for example to share raw code allowing you to use the
code in other projects and be able to keep the scopes as internal.

Again, I think that's a really bad idea for maintainability.
Some benefits of the compiler handling the scenario like this is that this way
you wont have the nightmare when implementing == <> etc when using generics.

Yes, it's a shame that you can't specify operators in generic
constraints - but I believe there are *much* better solutions to that
than the one you're proposing.

If you want a dynamically typed language, use one - but I don't believe
it's a good idea to try to bend a statically typed language into a
dynamically typed one.

Jon
 
You can't do it. Reflection will allow you to parameterize a type from
any type. So if I have a type that represents a parameterized type, I can
use reflection (even on internal and private classes, with the right
permissions) to create the fully defined type.

The compiler could NEVER guarantee that the type will never be used
outside of the environment where it is created. Whether or not it is
practical, that's another thing, but that's not for the compiler to decide.
 

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

Back
Top