In Java, is it possible to attempt a cast and get back null if the cast fails?
public static <T> T as(Class<T> t, Object o) {
return t.isInstance(o) ? t.cast(o) : null;
}
Usage:
MyType a = as(MyType.class, new MyType());
// 'a' is not null
MyType b = as(MyType.class, "");
// b is null
You can use the instanceof keyword to determine if you can cast correctly.
return obj instanceof String?(String)obj: null;
Of course it can be genericied and made into the function, but I think question was about what means Java have to accomplish this.
You can, but not with a single function in Java:
public B nullCast(Object a) {
if (a instanceof B) {
return (B) a;
} else {
return null;
}
}
EDIT: Note that you can't make the B class generic (for this example) without adding the target class (this has to do with the fact that a generic type is not available to instanceof):
public <V, T extends V> T cast(V obj, Class<T> cls) {
if (cls.isInstance(obj)) {
return cls.cast(obj);
} else {
return null;
}
}
MyType e = ( MyType ) orNull( object, MyType.class );
// if "object" is not an instanceof MyType, then e will be null.
...
public static Object orNull( Object o , Class type ) {
return type.isIntance( o ) ? o : null;
}
I guess this could somehow done with generics also but I think but probably is not what is needed.
This simple method receives Object and returns Object because the cast is performed in the method client.
AFAIK, this would be (one) of the ways to do that:
SomeClassToCastTo object = null;
try {
SomeClassToCastTo object = SomeClassToCastTo.class.cast(anotherObject);
}
catch (ClassCastException e) {
object = null;
}
Ugly, but it should do what you want...
In Java if a cast fails you will get a ClassCastException. You can catch the exception and set the target object to null.
You can either catch the exception:
Foo f = null;
try {
f = Foo(bar);
}
catch (ClassCastException e) {}
or check the type:
Foo f = null;
if (bar instanceof Foo)
f = (Foo)bar;
The two solutions above are somewhat awkward:
Casting and catching ClassCastException: creating the exception object can be expensive (e.g. computing the stack trace).
The nullCast method described earlier means you need a cast method for each cast you want to perform.
Generics fail you because of "type erasure" ...
You can create a static helper method that is guaranteed to return an instance of your target class or null, and then cast the result without fear of exception:
public static Object nullCast(Object source, Class target) {
if (target.isAssignableFrom(source.getClass())) {
return target.cast(source);
} else {
return null;
}
}
Sample call:
Foo fooInstance = (Foo) nullCast(barInstance, Foo.class);
you can handle this catching ClassCastException
Related
I am working on a C# generic function. When error, if the generic type can be new-able, return new T(), otherwise return default(T).
The code like this:
private T Func<T>()
{
try
{
// try to do something...
}
catch (Exception exception)
{
if (T is new-able) // <---------- How to do this?
{
return new T();
}
else
{
return default(T);
}
}
}
I know it needs where T : new() for those using new T(). This question is, how to judge this on runtime?
You just need to check whether the type has a parameterless constructor. You do it by callingType.GetConstructor method with empty types as parameter.
var constructorInfo = typeof(T).GetConstructor(Type.EmptyTypes);
if(constructorInfo != null)
{
//here you go
object instance = constructorInfo.Invoke(null);
}
If I remember correctly, Activator.CreateInstance<T> will return an object constructed with the parameterless constructor if T is a class or a default(T) if T is a struct.
You can use the technique in Sriram's answer to first make sure a parameterless constructor exists for T.
You could something like checking for a default constructor and execute new T() if one is found.
To do this you could use something like:
var constructor = typeof(T).GetConstructor(Type.EmptyTypes);
if(constructor != null)
{
return (T)constructor.Invoke(null);
}
else
{
return default(T);
}
I little played with MarcoLaser's answer and made my
'if T is newable then get instance constructor'
public class MyClass<T>
{
public MyClass()
{
var constructor = typeof(T).GetConstructor(Type.EmptyTypes);
if (constructor != null)
Data = (T)constructor.Invoke(null);
}
public T Data { get; set; }
}
If I have:
void MyMethod(Object obj) { ... }
How can I cast obj to what its actual type is?
If you know the actual type, then just:
SomeType typed = (SomeType)obj;
typed.MyFunction();
If you don't know the actual type, then: not really, no. You would have to instead use one of:
reflection
implementing a well-known interface
dynamic
For example:
// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);
// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();
// dynamic
dynamic d = obj;
d.MyFunction();
I don't think you can (not without reflection), you should provide a type to your function as well:
void MyMethod(Object obj, Type t)
{
var convertedObject = Convert.ChangeType(obj, t);
...
}
UPD:
This may work for you:
void MyMethod(Object obj)
{
if (obj is A)
{
A a = obj as A;
...
}
else if (obj is B)
{
B b = obj as B;
...
}
}
How about
JsonConvert.DeserializeObject<SomeType>(object.ToString());
You could use also Pattern Matching
void MyMethod(Object obj) {
if(obj is SomeType myVar){
myVar.MyFunction();
}
}
If your MyFunction() method is defined only in one class (and its descendants), try
void MyMethod(Object obj)
{
var o = obj as MyClass;
if (o != null)
o.MyFunction();
}
If you have a large number in unrelated classes defining the function you want to call, you should define an interface and make your classes define that interface:
interface IMyInterface
{
void MyFunction();
}
void MyMethod(Object obj)
{
var o = obj as IMyInterface;
if (o != null)
o.MyFunction();
}
In my case AutoMapper works well.
AutoMapper can map to/from dynamic objects without any explicit configuration:
public class Foo {
public int Bar { get; set; }
public int Baz { get; set; }
}
dynamic foo = new MyDynamicObject();
foo.Bar = 5;
foo.Baz = 6;
Mapper.Initialize(cfg => {});
var result = Mapper.Map<Foo>(foo);
result.Bar.ShouldEqual(5);
result.Baz.ShouldEqual(6);
dynamic foo2 = Mapper.Map<MyDynamicObject>(result);
foo2.Bar.ShouldEqual(5);
foo2.Baz.ShouldEqual(6);
Similarly you can map straight from dictionaries to objects, AutoMapper will line up the keys with property names.
more info https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping
Cast it to its real type if you now the type for example it is oriented from class named abc.
You can call your function in this way :
(abc)(obj)).MyFunction();
if you don't know the function it can be done in a different way. Not easy always. But you can find it in some way by it's signature. If this is your case, you should let us know.
If multiple types are possible, the method itself does not know the type to cast, but the caller does, you might use something like this:
void TheObliviousHelperMethod<T>(object obj) {
(T)obj.ThatClassMethodYouWantedToInvoke();
}
// Meanwhile, where the method is called:
TheObliviousHelperMethod<ActualType>(obj);
Restrictions on the type could be added using the where keyword after the parentheses.
Another option is to serialise it and then deserialise it as the object you want.
JsonConvert.DeserializeObject<OtherType>(JsonConvert.SerializeObject(obj));
Implement an interface to call your function in your method
interface IMyInterface
{
void MyinterfaceMethod();
}
IMyInterface MyObj = obj as IMyInterface;
if ( MyObj != null)
{
MyMethod(IMyInterface MyObj );
}
Casting to actual type is easy:
void MyMethod(Object obj) {
ActualType actualyType = (ActualType)obj;
}
What would be the best way of getting the type of items a generic list contains? It's easy enough to grab the first item in the collection and call .GetType(), but I can't always be sure there will be an item in the collection.
Hope that makes sense.
Thanks,
Sonny
You could use the Type.GetGenericArguments method for this purpose.
List<Foo> myList = ...
Type myListElementType = myList.GetType().GetGenericArguments().Single();
For a more robust approach:
public static Type GetListType(object someList)
{
if (someList == null)
throw new ArgumentNullException("someList");
var type = someList.GetType();
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(List<>))
throw new ArgumentException("Type must be List<>, but was " + type.FullName, "someList");
return type.GetGenericArguments()[0];
}
But if your variable is typed List<T> then you can just use typeof(T). For example:
public static Type GetListType<T>(List<T> someList)
{
return typeof(T);
}
Note that you don't really even need the someList parameter. This method is just an example for how you could use typeof if you are already in a generic method. You only need to use the reflection approach if you don't have access to the T token (the list is stored in a non-generic-typed variable, such as one typed IList, object, etc.).
list.GetType().GetGenericArguments()[0]
Here's another way which works for non-generic collections, too:
static Type GetItemType(Type collectionType)
{
return collectionType.GetMethod("get_Item").ReturnType;
}
That is, get the return type of foo[x], where foo is of the specified type.
Examples:
// Generic type; prints System.Int32
Console.WriteLine(GetItemType(typeof(List<int>)));
// Non-generic type; prints System.String
Console.WriteLine(GetItemType(typeof(System.Collections.Specialized.StringCollection)));
The GetItemType method above has a couple issues, though:
It throws a NullReferenceException if the type has no indexing operator.
It throws an AmbiguousMatchException if the type has multiple overloads for the indexing operator (e.g. this[string] and this[int]).
Here is a more refined version:
public static Type GetItemType(this Type collectionType)
{
var types =
(from method in collectionType.GetMethods()
where method.Name == "get_Item"
select method.ReturnType
).Distinct().ToArray();
if (types.Length == 0)
return null;
if (types.Length != 1)
throw new Exception(string.Format("{0} has multiple item types", collectionType.FullName));
return types[0];
}
What about this, its all static (e.g. no instances required), and fast (no loops, no usage of linq), and it is simple :) these work for collections:
[System.Diagnostics.DebuggerHidden]
public static Type GetIndexedType(this ICollection poICollection)
{
PropertyInfo oPropertyInfo = poICollection == null ? null : poICollection.GetType().GetProperty("Item");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
[System.Diagnostics.DebuggerHidden]
public static Type GetEnumeratedType(this ICollection poICollection)
{
PropertyInfo oPropertyInfo = poICollection == null ? null : poICollection.GetType().GetMethod("GetEnumerator").ReturnType.GetProperty("Current");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
And a few simple unit tests:
[Test]
public void GetIndexedType()
{
Assert.AreEqual(null, ((ICollection)null).GetIndexedType());
Assert.AreEqual(typeof(int), (new List<int>()).GetIndexedType());
Assert.AreEqual(typeof(bool), (new SortedList<string, bool>()).GetIndexedType());
}
[Test]
public void GetEnumeratedType()
{
Assert.AreEqual(null, ((ICollection)null).GetEnumeratedType());
Assert.AreEqual(typeof(int), (new List<int>()).GetEnumeratedType());
Assert.AreEqual(typeof(KeyValuePair<string, bool>), (new SortedList<string, bool>()).GetEnumeratedType());
}
Notice the fact that there are two ways to look at this, one type may be returned by the indexer and an other type may be returned by the enumerator. The unit test do show both.
Have fun,
Frans.
P.s. For enumerables:
[System.Diagnostics.DebuggerHidden]
public static Type GetEnumeratedType(this System.Collections.IEnumerable poIEnumerable)
{
PropertyInfo oPropertyInfo = poIEnumerable == null ? null : poIEnumerable.GetType().GetMethod("GetEnumerator").ReturnType.GetProperty("Current");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
And for enumerator:
[System.Diagnostics.DebuggerHidden]
public static Type GetEnumeratedType(this System.Collections.IEnumerator poIEnumerator)
{
PropertyInfo oPropertyInfo = poIEnumerator == null ? null : poIEnumerator.GetType().GetProperty("Current");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
public Type GetType(IEnumerable<object> resultList)
{
return resultList.GetType().GetElementType();
}
Old question new method with dynamic
void Foo(){
Type type GetTypeT(data as dynamic);
}
private static Type GetTypeT<T>(IEnumerable<T> data)
{
return typeof(T);
}
Public Shared Function ListItemType(ListType As System.Type) As System.Type
If Not ListType.IsGenericType Then
If ListType.BaseType IsNot Nothing AndAlso ListType.BaseType.IsGenericType Then
Return ListItemType(ListType.BaseType)
End If
Else
Return ListType.GetGenericArguments.Single
End If
End Function
Here is a solution that also works with derived classes.
Because with this class :
public class SubList : List<int>
{ }
If you call : subList.GetType().GetGenericArguments().Single()
It will throws a System.InvalidOperationException
With this method it works for derived classes :
public Type GetListItemType<T>(List<T> list)
{
Type type = list.GetType();
while (type != typeof(List<T>))
type = type.BaseType;
return type.GetGenericArguments().Single();
}
var list = new List<int>();
var subList = new SubList();
Console.WriteLine(GetListItemType(list)); // System.Int32
Console.WriteLine(GetListItemType(subList)); // System.Int32
I have next code:
private T CreateInstance<T>(object obj) // where T : ISomeInterface, class
{
...
if (!typeof(T).IsAssignableFrom(obj.GetType())) { throw ..; }
return (T)obj;
}
Can it be replaced with this:
T result = obj as T;
if (result == null) { throw ..; }
return result;
If not - why?
What about if (!(bar is T)) { throw ..; }
Alternatively if you don't need your own exception message the simplest answer is just to do:
return (T)obj;
The reason if that if it's not castable an InvalidCastException will be thrown and the return ignored. Unless you're adding some more logic or a custom error message there's no need to do a check and throw your own exception.
Another variant:
private T CreateInstance<T>(object obj) where T : ISomeInterface // as OP mentioned above
{
...
T result = obj as T;
if (result == null)
{ throw ..; }
else
return result;
}
Yes you can use your as operator code there instead of the original code, so long as T is a reference type or nullable.
as is the recommended way of casting in C# (see item 3 of Effective C#, by Bill Wagner)
From system.type.isassignablefrom:
[returns] true if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c, or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c. false if none of these conditions are true, or if c is null.
From 7.10.11 of the C# spec:
In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type
So you can see that they do comparable checks.
Maybe this (less brackets, better readability)
if (obj is T)
{
return (T)obj;
}
else
throw new ...
EDITED
by reduced number of brackets I originally meant inverted check: ie
if (obj is T)
instead of
if (!(obj is T))
so final version can be
if (obj is T)
{
return (T)obj;
}
throw new ...
or
if (obj is T)
{
return (T)obj;
}
else
{
throw new ...
}
See this post
The second one is safe...because at the first one if obj is null you will get exception (obj.GetType() --> NullReferenceException).
When you place "is" and then "as" is cause performance issues..
The class constraint where T : class allows you to use the as T statement.
private T CreateInstance<T>(object obj) where T : class
{
if (!(obj is T)) { throw new ArgumentException("..."); }
return obj as T;
}
or
private T CreateInstance<T>(object obj)
{
if (!(obj is T)) { throw new ArgumentException("..."); }
return (T)obj;
}
You're probably looking for the is keyword, with the syntax expression is type
Documentation describes it as performing the checks you want:
An is expression evaluates to true if
both of the following conditions are
met:
• expression is not null.
• expression
can be cast to type. That is, a cast
expression of the form
(type)(expression) will complete
without throwing an exception.
Edit
However, if instead of just working out whether you can cast something before you try, the as keyword is probably your best solution as you describe in your post.
The following code would perform the same function though...
try
{
T result = (T)obj;
return result;
}
catch (InvalidCastException ex)
{
// throw your own exception or deal with it in some other way.
}
Which method you prefer is up to you...
IsAssignableFrom used by this scene:
foreach (PropertyInfo property in GetType().GetProperties())
{
if (typeof(SubPresenter).IsAssignableFrom(property.PropertyType))
{//Do Sth.}
}
Just for the developers who like to play the numbers game (who doesn't!).
Below you'll find a performance comparison test for IsAssignableFrom vs. As. Of course this will only count if you have an instance.
The result of the test (one million attempts):
IsAssignableFrom: 146 ms elapsed
AsOperator: 7 ms elapsed
[TestMethod]
public void IsAssignableFromVsAsPerformanceTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int attempts = 1000000;
string value = "This is a test";
for (int attempt = 0; attempt < attempts; attempt++) {
bool isConvertible = typeof(IConvertible).IsAssignableFrom(value.GetType());
}
stopwatch.Stop();
Console.WriteLine("IsAssignableFrom: {0} ms elapsed", stopwatch.ElapsedMilliseconds);
stopwatch.Restart();
for (int attempt = 0; attempt < attempts; attempt++) {
bool isConvertible = value as string != null;
}
stopwatch.Stop();
Console.WriteLine("AsOperator: {0} ms elapsed", stopwatch.ElapsedMilliseconds);
}
It may have been intended to handle cases where a conversion constructor would allow the operation, but apparently IsAssignableFrom doesn't handle that either. Don't see anything that can handle that. So I don't see how to check for cases like this:
class Program
{
static void Main(string[] args)
{
B bValue = new B(123);
Console.WriteLine(typeof(A).IsAssignableFrom(bValue.GetType()));
//Console.WriteLine(bValue is A);
//Console.WriteLine(bValue as A == null);
A aValue = bValue;
Console.WriteLine(aValue.ToString());
}
}
class A
{
string value;
public A(string value)
{
this.value = value;
}
public override string ToString()
{
return value;
}
}
class B
{
int value;
public B(int value)
{
this.value = value;
}
public static implicit operator A(B value)
{
return new A(value.value.ToString());
}
}
In the end, I don't see any reason why you wouldn't want to use your version of the code, unless you want the code to throw an exception when obj is null. That's the only difference I can see. obj.GetType() will throw an null reference exception when obj is null instead of throwing the specified exception.
Edit: I see now your version of the code will not compile if T can be a value type, but the other suggested solution like "if (obj is T) return (T)obj;" will compile. So I see why your suggested alternative will not work, but I don't see why you couldn't use "is".
Or even better because its easer to read true conditionals.
if(obj is T){
//Create instance.
}
else{
throw new InvalidArgumentException("Try Again");
}
If I have a method with a parameter that's an interface, whats the fasts way to see if the interface's reference is of a specific generic type?
More specifically, if I have:
interface IVehicle{}
class Car<T> : IVehicle {}
CheckType(IVehicle param)
{
// How do I check that param is Car<int>?
}
I'm also going to have to cast after the check. So if there is a way to kill 2 birds with one stone on this one let me know.
To check if param is a Car<int> you can use "is" and "as" as normal:
CheckType(IVehicle param)
{
Car<int> car = param as Car<int>;
if (car != null)
{
...
}
}
Or, you can just do:
if(param is Car<int>)
{
// Hey, I'm a Car<int>!
}
Why not make this generic?
interface IVehicle{}
class Car<T> : IVehicle {
public static bool CheckType(IVehicle param)
{
return param is Car<T>;
}
}
...
Car<string> c1 = new Car<string>();
Car<int> c2 = new Car<int>();
Console.WriteLine(Car<int>.CheckType(c1));
Console.WriteLine(Car<int>.CheckType(c2));
The code differs quite dramatically depending on whether you want to know, if the reference is based on a generic type prototype, or a specialized one.
The specialized one is easy, you can just use is:
CheckType(IVehicle param)
{
var isofYourType = param is Car<int>;
...
}
or a safe cast, as shown before:
CheckType(IVehicle param)
{
var value = param as Car<int>;
if(value != null)
...
}
In case you wanted to know whether yur var is just some specialization of Car<T>, things get really ugly.
And the last you should thing to worry about is speed in this case, because that's gonna be even uglier than the code g:
class Car<T>
{ }
interface IVehicle { }
class YourCar : Car<int>, IVehicle
{ }
static bool IsOfType(IVehicle param)
{
Type typeRef = param.GetType();
while (typeRef != null)
{
if (typeRef.IsGenericType &&
typeRef.GetGenericTypeDefinition() == typeof(Car<>))
{
return true;
}
typeRef = typeRef.BaseType;
}
return false;
}
static void Main(string[] args)
{
IVehicle test = new YourCar();
bool x = IsOfType(test);
}
I often find that if my code requires me to write checks for specific types, I'm probably doing something wrong. You didn't give us enough context for us to give advice on this, though.
Does this meet your needs?
Car<int> carOfInt = param as Car<int>;
if (carOfInt != null)
{
// .. yes, it's a Car<int>
}
Use the "as" operator to do it all in one shot. "as" will return either an object of the type you want, or null if what you're checking against doesn't match. This will only work for reference types, though.
interface IVehicle { }
class Car<T> : IVehicle
{
static Car<int> CheckType(IVehicle v)
{
return v as Car<int>;
}
}
The "is" operator will let you test to see if v is an instance of Car<int>.