How to write a generic method in Java - c#

How to write a generic method in Java.
In C# I would do this
public static T Resolve<T>()
{
return (T) new object();
}
Whats the equivalent in Java?

First, your C# example is wrong; it will throw an InvalidCastException unless typeof(T) == typeof(object). You can fix it by adding a constraint:
public static T Resolve<T>() where T : new() {
return new T();
}
Now, this would be the equivalent syntax in Java (or, at least, as close as we can get):
public static <T> T Resolve() {
return (T) new T();
}
Notice the double mention of T in the declaration: one is the T in <T> which parameterizes the method, and the second is the return type T.
Unfortunately, the above does not work in Java. Because of the way that Java generics are implemented runtime type information about T is not available and so the above gives a compile-time error. Now, you can work around this constraint like so:
public static <T> T Resolve(Class<T> c) {
return c.newInstance();
}
Note the need to pass in T.class. This is known as a runtime type token. It is the idiomatic way of handling this situation.

As other commenters have pointed out, you can do this with Java as well - with as much of a possibility to create a casting exception at runtime:
#SuppressWarnings("unchecked")
public static <T> T resolve() {
return (T) new Object();
}
Unless you use the #SuppressWarnings annotation, however, Java's type erasure comes into play and you will get a compiler warning. The exception will also occur somewhere else: whereever you are trying to use it:
String s = <String>resolve();
will throw the exception.
On the other hand, you probably wanted to use new T() in C# anyway. This you cannot do in Java. The suggested workaround is to use Class<T> as a type parameter if you need to rely on type information at runtime. For your example, this would mean that you have to refactor it to this version:
public static <T> T resolve(Class<T> type) {
try {
return type.newInstance();
} catch(Exception e) {
// deal with the exceptions that can happen if
// the type doesn't have a public default constructor
// (something you could write as where T : new() in C#)
}
}
By the way, you can use this also to get rid of the warning in the previous case and to place the runtime exception at a more sensible line:
public static <T> T resolve(Class<T> type) {
return type.cast(new Object());
}
This piece of code will behave exactly like the one you gave as an example - including an exception that occurs when T is any type different from Object.

Try this http://java.sun.com/docs/books/tutorial/extra/generics/methods.html
public static <T> T Resolve()
{
return (T) new Object();
}
Be careful about (T) but I am not sure that this is correct. I know that generic cast causes a lot of problems. I have already spent with it a lot of time...

You want some kind of factory:
public interface MyFactory<T> {
T newInstance();
}
Then that can be passed into where it is needed. In your code:
public static T resolve<T>(MyFactory<T> factory) {
return factory.newInstance();
}
Note: There is absolutely no reason to be using reflection for this!!

Related

new() constraint calling Activator.CreateInstance [duplicate]

When you have code like the following:
static T GenericConstruct<T>() where T : new()
{
return new T();
}
The C# compiler insists on emitting a call to Activator.CreateInstance, which is considerably slower than a native constructor.
I have the following workaround:
public static class ParameterlessConstructor<T>
where T : new()
{
public static T Create()
{
return _func();
}
private static Func<T> CreateFunc()
{
return Expression.Lambda<Func<T>>( Expression.New( typeof( T ) ) ).Compile();
}
private static Func<T> _func = CreateFunc();
}
// Example:
// Foo foo = ParameterlessConstructor<Foo>.Create();
But it doesn't make sense to me why this workaround should be necessary.
I suspect it's a JITting problem. Currently, the JIT reuses the same generated code for all reference type arguments - so a List<string>'s vtable points to the same machine code as that of List<Stream>. That wouldn't work if each new T() call had to be resolved in the JITted code.
Just a guess, but it makes a certain amount of sense.
One interesting little point: in neither case does the parameterless constructor of a value type get called, if there is one (which is vanishingly rare). See my recent blog post for details. I don't know whether there's any way of forcing it in expression trees.
This is likely because it is not clear whether T is a value type or reference type. The creation of these two types in a non-generic scenario produce very different IL. In the face of this ambiguity, C# is forced to use a universal method of type creation. Activator.CreateInstance fits the bill.
Quick experimentation appears to support this idea. If you type in the following code and examine the IL, it will use initobj instead of CreateInstance because there is no ambiguity on the type.
static void Create<T>()
where T : struct
{
var x = new T();
Console.WriteLine(x.ToString());
}
Switching it to a class and new() constraint though still forces an Activator.CreateInstance.
Why is this workaround necessary?
Because the new() generic constraint was added to C# 2.0 in .NET 2.0.
Expression<T> and friends, meanwhile, were added to .NET 3.5.
So your workaround is necessary because it wasn't possible in .NET 2.0. Meanwhile, (1) using Activator.CreateInstance() was possible, and (2) IL lacks a way to implement 'new T()', so Activator.CreateInstance() was used to implement that behavior.
Interesting observation :)
Here is a simpler variation on your solution:
static T Create<T>() where T : new()
{
Expression<Func<T>> e = () => new T();
return e.Compile()();
}
Obviously naive (and possible slow) :)
This is a little bit faster, since the expression is only compiled once:
public class Foo<T> where T : new()
{
static Expression<Func<T>> x = () => new T();
static Func<T> f = x.Compile();
public static T build()
{
return f();
}
}
Analyzing the performance, this method is just as fast as the more verbose compiled expression and much, much faster than new T() (160 times faster on my test PC) .
For a tiny bit better performance, the build method call can be eliminated and the functor can be returned instead, which the client could cache and call directly.
public static Func<T> BuildFn { get { return f; } }

Explicit casting vs using 'as' inside a generic method [duplicate]

This question already has answers here:
Cast from Generics<T> to Specific SubClass
(9 answers)
Closed 7 years ago.
I have a simple interface and two classes implement it:
public interface IMovable { }
public class Human : IMovable { }
public class Animal : IMovable { }
The following generic method results in a compile-time error: Cannot convert type 'Human' to 'T'
public static T DoSomething<T>(string typeCode) where T : class, IMovable
{
if (typeCode == "HUM")
{
return (T)new Human(); // Explicit cast
}
else if (typeCode == "ANI")
{
return (T)new Animal(); // Explicit cast
}
else
{
return null;
}
}
But when the as keyword is used, all is fine:
public static T DoSomething<T>(string typeCode) where T : class, IMovable
{
if (typeCode == "HUM")
{
return new Human() as T; // 'as'
}
else if (typeCode == "ANI")
{
return new Animal() as T; // 'as'
}
else
{
return null;
}
}
Why does as work but explicit cast doesn't?
Short answer is, because T doesn't have to be of the correct type. Compiler is really trying to help you here, because you are doing something which might easily fail in runtime.
E.g. consider what happens with:
var result = DoSomething<Human>("ANI");
Longer answer is, you shouldn't be casting at all. Casting indicates problems with your OOP design, and is especially wrong when using generics: you lose the whole point of generics, actually. Generics are supposed to allow you create a "template" which abstracts away the actual type, leaving you to worry about the algorithm itself instead of concrete types.
In this case, you probably don't need generics at all. Your method is basically a less safer way of doing this:
public static T DoSomething<T>() where T : new()
{
return new T();
}
or this:
public static IMovable DoSomething(string typeCode)
{
if (typeCode == "HUM")
return new Human();
if (typeCode == "ANI")
return new Animal();
return null;
}
To silence the compiler, you may also add an intermediate cast, which tells the compiler you went an extra step to indicate that you really want to cast it this way: For example, using
(T)(object)new Human()
or
(T)(IMovable)new Human()
will both pass compilation, although the conversion from IMovable to T is no safer than the original code, and casting an object to T even unsafer. But this is not the solution to your underlying issue, which is design related.
With your code, it is perfectly possible to call DoSomething<Animal>, and then you have (Animal)new Human().
That is biologically correct, but your model does not allow it.
Do you really need generics here? Maybe you just want to return IMovable in this case.
Under the covers, the 'as' will do an 'is' check first before attempting the cast. So it will not attempt it if it can't cast it and will then return null.

C# casting generic parameter to interface

I need help with casting generic paremetrs down to an interface.
I have prebaked code like this:
public interface InterFoo<T> {...}
public InterFoo<T> specialFoo<T>() where T : InterFoo<T> {...}
public InterFoo<T> regularFoo<T>() {...}
and i want to implement something like this
public InterFoo<T> adaptiveFoo<T>()
{
if (T is InterFoo<T>)
return specialFoo<T as InterFoo>();
return regularFoo<T>();
}
at this point I cant find any solution so anything would be helpful, thanks.
EDIT: originally the functions had returned an int but that has a simpler solution that is incompatible with the code's intended purpose, the functions have been changed to request a generic type.
The is and as operators only compile for types that the compiler knows can be null (nullable value types or reference types).
You can try a call to IsAssignableFrom:
public int adaptiveFoo<T>()
{
if (typeof(InterFoo<T>).IsAssignableFrom(typeof(T))
return specialFoo<InterFoo>();
return regularFoo<T>();
}
** Update to reflect changes in question **
Type constraints are, unfortunately viral, in order for your method to compile (when keeping with strict type checking from the compiler) you would need the constraint to be added to this method also. However, reflection can circumvent this restriction:
Your method would be:
public InterFoo<T> adaptiveFoo<T>()
{
if (typeof(InterFoo<T>).IsAssignableFrom(typeof(T))
{
var method = typeof (Class1).GetMethod("specialFoo");
var genericMethod = method.MakeGenericMethod(typeof(T));
return (Interfoo<T>)method.Invoke(this, null);
}
return regularFoo<T>();
}

C# - How are we supposed to implement default(T) in Interfaces?

Put default(T) in an interface. Explicitly implement the interface. The result does not compile
public interface IWhatever<T>
{
List<T> Foo(T BarObject = default(T));
}
public class ConcreteWhatever: IWhatever<ConcreteWhatever>
{
List<ConcreteWhatever> Foo(ConcreteWhatever BarObject = default(T)) {}
}
I fully expect default(ConcreteWhatever). What I get is default(T) which results in a compilation error.
I just go in and replace default(T) with null and things are fine. But this is hideous. Why is this happening?
You don't have a T in this case, because ConcreteWherever isn't a generic type.
If you want default(ConcreteWhatever) then that's the code you should write.
Are you just complaining about the code auto-generated by Visual Studio? If so, that's a reasonable complaint, but it would be worth being explicit about it... (Note that you're not using explicit interface implementation here - otherwise it would be declared as IWhatever<ConcreteWhatever>.Foo. You don't really have properly implicit implementation either, as otherwise it should be public...)
EDIT: I've just tried the same thing myself, and seen the same result, except the method is made public. Looks like it's just a fault with Visual Studio - I suggest you create a Connect request for it. It's a relatively rare situation though, I suspect - creating a generic interface which specifies an optional parameter which uses the default value of a type parameter as the value...
Shouldn't this line:
List<ConcreteWhatever> Foo(ConcreteWhatever BarObject = default(T)) {}
be:
List<ConcreteWhatever> Foo(ConcreteWhatever BarObject = default(ConcreteWhatever)) {}
public interface IWhatever<T>
{
List<T> Foo(T BarObject = default(T));
}
public class ConcreteWhatever : IWhatever<ConcreteWhatever>
{
public List<ConcreteWhatever> Foo(ConcreteWhatever BarObject = default(ConcreteWhatever))
{
return null; // replace with proper code
}
}

How to convert a type to a generic version given its type?

I'm having a spot of trouble with generics in C#. I have to store a number of generic objects together but their type parameter differs so I have made a non-generic interface which they implement. What I'm looking for is a way to convert back to the generic version, given a type object. I know I can do it with reflection but I was wondering if there was a better/more elegant solution.
The following code illustrates the problem:
interface ITable
{
public Type Type { get; }
}
class Table<T> : ITable
{
public Type Type { get{ return typeof(T); } }
}
class Program
{
static void Main(string[] args)
{
var tables = new Dictionary<string, ITable>();
... //insert tables
DoStuffWithTable(tables["my table"]); //This doesn't work
}
public static void DoStuffWithTable<T>(Table<T> table)
{
...//Some work
}
}
Is there a clean way for me to invoke the generic DoStuffWithTable method based on the instance of the Type object I can get from its interface method?
If you are starting from a non-generic type (ITable), then the only way to do this is via reflection (MakeGenericMethod). It isn't very pretty or especially fast, but it works...
public static void DoStuffWithUntypedTable(ITable table)
{
typeof(Program).GetMethod("DoStuffWithTable")
.MakeGenericMethod(table.Type)
.Invoke(null, new object[] { table });
}
As an aside - note that there is a bit of risk in assuming that an ITable is actually a Table<T> - you should probably verify that, and maybe also use an interface (ITable<T>).
Edit: if it really must be a Table<T>, then you can enforce this (including subclass support, such as FooTable : Table<Foo> as:
public static void DoStuffWithUntypedTable(object table)
{
Type type = table.GetType();
while (type != typeof(object))
{
if (type.IsGenericType && type.GetGenericTypeDefinition()
== typeof(Table<>))
{
typeof(Program).GetMethod("DoStuffWithTable")
.MakeGenericMethod(type.GetGenericArguments()[0])
.Invoke(null, new object[] { table });
return;
}
type = type.BaseType;
}
throw new ArgumentException("Not a Table<T> or subclass");
}
The problem is that you don't know the type at compile-time - which is what generics is tailored for.
To call a generic method where you only know the type argument at execution time, you basically need reflection - get the generic method, call MakeGenericMethod and then invoke the returned method.
You need to cast, you actually need to know the actual type, unless it doesn't make sense.
DoStuffWithTable<MyType>((Table<MyType>)tables["my table"]);
You should consider to make the method not generic if you want to call it without knowing the actual type.
There is a misunderstanding here between generics and polymorphism. Generally, generics deal with things of a single type where the type is defined at compile time*, whereas polymorphism is about things of different types that exhibit common functionality defined as an interface or base type.
You seem to be trying to create a polymorphic type (things of different type that exhibit the same behaviour) where each polymorphic instance is defined by a generic type.
So, to update your code:
interface ITable
{
void SomeCommonFunction ();
}
class Table<T> : ITable
{
void SomeCommonFunction () { do something - T is known at compile time! }
}
class Program
{
static void Main(string[] args)
{
var tables = new Dictionary<string, ITable>();
... //insert tables
tables["my table"].SomeCommonFunction ();
}
}
Now, if you want to do different things in SomeCommonFunction that is dependant on the type T, then you want to have specific instantiations of the Table type. C# doesn't allow for specialisations of generic type in the way that C++ can with its templates so you'll have to do:
class TableOfInt : ITable
{
void SomeCommonFunction () { do something different! }
}
* You can define the type at run time in C# but that's getting into crazy reflection territory.

Categories

Resources