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; }
}
Related
I need to declare a Dictionary having a Type as key and an instance as value.
I need to limit key Type to a certain class hierarchy.
For a Java Map, I can do something like:
Map<Class<? extends MySuperClass>, ? extends MySuperClass>
How can I achieve this in C#?
Do not expose Dictionary directly, this way you can control manually when to add
public void AddToDictionary(Type key, object value)
{
if(!key.IsAssignableFrom(typeof(SomeBaseClass))
throw new ArgumentException("Must be an inherited from SomeBaseClass type");
dictionary.Add(key, value);
}
I think Sinatr's approach of exposing a method for adding to the dictionary instead of the dictionary itself is a very good idea. The only downside is that you get no compile time safety; if some code added an object of the wrong type you wouldn't find out till runtime.
Using generics, however, we can tweak the method so that adding objects is foolproof:
public void AddToDictionary<T>(T value) where T: MySuperClass
{
dict.Add(typeof(T), value);
}
Now it is impossible to write a program that adds objects of the wrong type and still compiles.
You could use typeof to get the type of the class so something like:
Map<System.Type, object>
I am not sure how you would enforce the extends for this. That should probably happen as a test before adding to the map.
You could:
public class MyType<TBase>
{
private Type Value;
protected MyType()
{
}
public static implicit operator Type(MyType<TBase> type)
{
return type.Value;
}
public static implicit operator MyType<TBase>(Type type)
{
if (type == null)
{
throw new ArgumentNullException();
}
if (!typeof(TBase).IsAssignableFrom(type))
{
throw new ArgumentException();
}
return new MyType<TBase> { Value = type };
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
var type = obj as MyType<TBase>;
return type != null && Value.Equals(type.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value.ToString();
}
}
and then:
Dictionary<MyType<MySuperClass>, MySuperClass> dict = new Dictionary<MyType<MySuperClass>, MySuperClass>();
dict.Add(typeof(MyClass1), new MyClass1());
The MyType has implicit operators from/to Type, so it is quite simple to use. You simply cast a Type to a MyType (or a MyType to a Type) and it just works. Example of TryGetValue():
MySuperClass ms;
if (!dict.TryGetValue(typeof(MyClass1), out ms))
{
throw new Exception();
}
Note that the checks are done at runtime!
Can I get the type of a field? Type.GetType(); only returns the type of an instance, so if field is set null I cant get the Type.
Note: I would prefer not using reflections~
Depending on context GetProperty and PropertyType may work for you. I.e. if you have object type and property name:
var typeOfLength = typeof(String).GetProperty("Length").PropertyType;
It's not clear whether you only want the compile time type when the field is null. A simple method like this could work:
public static class ReflectionExtensions
{
public static Type GetCompileTimeType<T>(this T obj)
{
return typeof(T);
}
}
You could modify it it check for null and return the actual type if that is what you want.
usage:
class A { }
class B : A { }
class C
{
private A a1, a2;
public C()
{
a2 = new B();
Console.WriteLine(a1.GetCompileTimeType()); // null but prints A
Console.WriteLine(a2.GetCompileTimeType()); // actually a B but prints A
}
}
public class test
{
private int fTestInt;
private string fTestString;
}
You can achieve getting the field type by typing fTestInt.GetType().
If you want a quick type validation you can use.
if (fTestInt is int)
{
Console.Write("I'm an int!");
}
Not sure if this is what you're asking. Your question seems partial.
Why not just ask if is null ?
if (Type != null)
{
return Type.GetType().Name;
}
else
{
return "";
}
I'm writing C# program, and VisualStudio's VSTO wizard generates below code.
private static string GetResourceText(string resourceName)
{
Assembly asm = Assembly.GetExecutingAssembly();
string[] resourceNames = asm.GetManifestResourceNames();
for (int i = 0; i < resourceNames.Length; ++i)
{
if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
{
using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
{
if (resourceReader != null)
{
return resourceReader.ReadToEnd();
}
}
}
}
return null;
}
I think if (resourceReader != null) is redundant, because constructor always returns not null. Isn't it?
In regular sane code, a constructor will not return null. There are some convoluted ways you can force a constructor to return null, but it is such a bizarre edge case that you will never see it. To all intents and purposes: new on this object will never return null - and it is completely pointless to add a null-check after a new(), especially for something sensible like StreamReader.
A simple case where you can get null:
object obj = new int?()
But this is simply exposing the subtle boxing behavior of nullable types. The more complicated way of getting a contructor to return null requires evil:
static void Main() {
var obj = new MyFunnyType(); // wow! null!
}
class MyFunnyProxyAttribute : ProxyAttribute {
public override MarshalByRefObject CreateInstance(Type serverType) {
return null;
}
}
[MyFunnyProxy]
class MyFunnyType : ContextBoundObject { }
According to ReSharper:
if (resourceReader != null)
Expression is always true
That's because the StreamReader constructor will never return null. In fact, I can't think of any time off my head where a constructor would ever return null.
Readline or other methods can return null but streamreader won't. Because you are assigning the instance in the same time you create it. So it is useless to check.
constructor return their class reference. and it is not null.
Constructors Should Not Return Null Values To Everywhere and On EveryTime
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
I have a class that I want to use to store "properties" for another class. These properties simply have a name and a value. Ideally, what I would like is to be able to add typed properties, so that the "value" returned is always of the type that I want it to be.
The type should always be a primitive. This class subclasses an abstract class which basically stores the name and value as string. The idea being that this subclass will add some type-safety to the base class (as well as saving me on some conversion).
So, I have created a class which is (roughly) this:
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
So the question is:
Is there a "generic" way to convert from string back to a primitive?
I can't seem to find any generic interface that links the conversion across the board (something like ITryParsable would have been ideal!).
I am not sure whether I understood your intentions correctly, but let's see if this one helps.
public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get { return (T)Convert.ChangeType(base.Value, typeof(T)); }
set { base.Value = value.ToString();}
}
}
lubos hasko's method fails for nullables. The method below will work for nullables. I didn't come up with it, though. I found it via Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Credit to "Tuna Toksoz"
Usage first:
TConverter.ChangeType<T>(StringValue);
The class is below.
public static class TConverter
{
public static T ChangeType<T>(object value)
{
return (T)ChangeType(typeof(T), value);
}
public static object ChangeType(Type t, object value)
{
TypeConverter tc = TypeDescriptor.GetConverter(t);
return tc.ConvertFrom(value);
}
public static void RegisterTypeConverter<T, TC>() where TC : TypeConverter
{
TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
}
}
For many types (integer, double, DateTime etc), there is a static Parse method. You can invoke it using reflection:
MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );
if (m != null)
{
return m.Invoke(null, new object[] { base.Value });
}
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)
TypeDescriptor is class having method GetConvertor which accept a Type object and then you can call ConvertFrom method to convert the value for that specified object.
With inspiration from the Bob's answer, these extensions also support null value conversion and all primitive conversion back and fourth.
public static class ConversionExtensions
{
public static object Convert(this object value, Type t)
{
Type underlyingType = Nullable.GetUnderlyingType(t);
if (underlyingType != null && value == null)
{
return null;
}
Type basetype = underlyingType == null ? t : underlyingType;
return System.Convert.ChangeType(value, basetype);
}
public static T Convert<T>(this object value)
{
return (T)value.Convert(typeof(T));
}
}
Examples
string stringValue = null;
int? intResult = stringValue.Convert<int?>();
int? intValue = null;
var strResult = intValue.Convert<string>();
You could possibly use a construct such as a traits class. In this way, you would have a parameterised helper class that knows how to convert a string to a value of its own type. Then your getter might look like this:
get { return StringConverter<DataType>.FromString(base.Value); }
Now, I must point out that my experience with parameterised types is limited to C++ and its templates, but I imagine there is some way to do the same sort of thing using C# generics.
Check the static Nullable.GetUnderlyingType.
- If the underlying type is null, then the template parameter is not Nullable, and we can use that type directly
- If the underlying type is not null, then use the underlying type in the conversion.
Seems to work for me:
public object Get( string _toparse, Type _t )
{
// Test for Nullable<T> and return the base type instead:
Type undertype = Nullable.GetUnderlyingType(_t);
Type basetype = undertype == null ? _t : undertype;
return Convert.ChangeType(_toparse, basetype);
}
public T Get<T>(string _key)
{
return (T)Get(_key, typeof(T));
}
public void test()
{
int x = Get<int>("14");
int? nx = Get<Nullable<int>>("14");
}
I used lobos answer and it works. But I had a problem with the conversion of doubles because of the culture settings. So I added
return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);
public class TypedProperty<T> : Property
{
public T TypedValue
{
get { return (T)(object)base.Value; }
set { base.Value = value.ToString();}
}
}
I using converting via an object. It is a little bit simpler.
Yet another variation. Handles Nullables, as well as situations where the string is null and T is not nullable.
public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get
{
if (base.Value == null) return default(T);
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
return (T)Convert.ChangeType(base.Value, type);
}
set { base.Value = value.ToString(); }
}
}
You can do it in one line as below:
YourClass obj = (YourClass)Convert.ChangeType(YourValue, typeof(YourClass));
Happy coding ;)