I'm saving a vector to sharedpreferences using Gson
This is my setters and getters but I seem to have some warning on my getter.
My setter doesn't have any warnings
Gson gson = new Gson();
String json = gson.toJson(al);
editor.putString("accountLabels", json);
editor.commit();
My getter warns me "Type safety: The expression of type Vector needs unchecked conversion to conform to Vector"
Gson gson = new Gson();
String json = myPref.getString("accountLabels", "Error");
Vector<AccountLabels> obj = gson.fromJson(json, Vector.class);
return obj;
I don't know how much of a work around it is to save objects or even vector of objects in sharedpreferences, but it seems like the best solution for me.
I'm not sure what the question is. I'm guessing it's to do with resolving the unchecked conversion warning. To do that, change
Vector<AccountLabels> obj = gson.fromJson(json, Vector.class);
to
Vector<AccountLabels> obj = gson.fromJson(json, new TypeToken<Vector<AccountLabels>>(){}.getType());
The warning is occurring because the fromJson method is returning type Vector, but it's being assigned to a reference of type Vector<AccountLabels>.
(Note: Since 2001 (I think) and the newer Collections API, use of Vector is frowned upon.)
Related
I have the following enum in groovy
public enum ImageTypes {
jpg ("image/jpeg"),
jpeg ("image/jpeg"),
jpe ("image/jpeg"),
jfif ("image/jpeg"),
bmp ("image/bmp"),
png ("image/png"),
gif ("image/gif"),
ief ("image/ief"),
tiff ("image/tiff"),
tif ("image/tiff"),
pcx ("image/pcx"),
pdf ("application/pdf"),
final String value
ImageTypes(String value) {
this.value = value
}
String getValue() {
return this.value
}
String toString(){
value
}
String getKey() {
name()
}
}
and I want to produce an ArrayList<String> of the keys or the values
What I am currently doing is looping through all the items and building the array list, but I'm thinking there has got to be a simple way to do this...
def imageTypes = ImageTypes.values()
def fileExts = new ArrayList<String>()
def mimeTypes = new ArrayList<String>()
for (type in imageTypes) {
fileExts.add(type.key)
mimeTypes.add(type.value)
}
ArrayList of keys
ImageTypes.values()*.name()
ArrayList of values
ImageTypes.values()*.value
There are two things to point out here.
1) I'm using the spread operator to call an action on each entry in a collection (although this case it's just an array), that's how the name() and value references are used.
2) I'm calling name() with parenthesis (as a method) because (I believe) it is an implicit attribute on the enum, whereas I'm just using the value attribute directly from the ImageTypes object for the values.
Expanding #mnd's answer -
The Spread Operator is the best choice, but if you're using Jenkins this won't work as is. To run the Spread Operator you will need to add #NonCPS in the Jenkins Pipeline DSL.
Another way to the list of enum keys is to directly use its Enumeration features.
ImageTypes.values().collect() { it.name() }
I am quite new to groovy, and I have found out that by making a field public, groovy provides getters and setters by default. Is there a way to have just the getters but not the setters by default?
The reason behind this is that I have a Builder and I don't want to provide access to the object fields for modification.
You can make the fields final and add the Canonical transform to get the c'tor created automatically for you. Or even easier use the Immutable transform:
#groovy.transform.Immutable
class A {
String x
}
def a = new A("x")
assert a.x == "x"
// a.x = "will fail"
// a.setX("will fail")
In any case, you should take a look into the builder transforms, what they have to offer for your use case.
Recently I'm developing a tiny framework for myself,
and I met this problem:
How can I do things like follow:
void object CreateDictionary(Type dictionaryType)
{
object dict = dictionaryType.GetConstructor(new Type[] {}).Invoke(new object[] {});
// Cast dict to its real type here so that I can add key-value-pairs to it.
...
}
The dictionaryType is the type of some kind of Dictionary, and is got via reflection.
I have no idea about the full type because I don't know the generic attributes until runtime.
I've also tried changing the declaration object dict to var dict, but it does not work either.
You cannot do this. But, you know that this is some kind of Dictionary, so you can cast it to IDictionary and use methods of IDictionary.
object CreateDictionary(Type dictionaryType)
{
object dict = dictionaryType.GetConstructor(new Type[] {}).Invoke(new object[] {});
var idictionary = (IDictionary)dict;
idictionary.Add(key, value);
}
If your all this dictionaries is inherited from one class, you can cast it to this class and use methods of this class.
By the way, it is simpler to get instance of Type through:
object obj = Activator.CreateInstance(type);
OK, I managed to solve this problem at last.
Finally I noticed that what I want to do is not about casting,
but calling method.
Maybe there are better solutions than mine.
Anyway, I'd like to share my solution.
First, create an extension class for object (this is weird though):
public static class ReflectionHelper
{
public static object InvokeInstanceMethod(this object invoker, string methodName, params object[] parameters)
{
MethodInfo[] methods = invoker.GetType().GetMethods();
foreach (MethodInfo method in methods)
{
ParameterInfo[] paramInfos = method.GetParameters();
if (method.Name == methodName && paramInfos.Length == parameters.Length)
{
for (int i = 0; i < parameters.Length; i++)
{
if (!paramInfos[i].ParameterType.IsAssignableFrom(parameters[i].GetType()))
{
throw new MissingMethodException();
}
}
return method.Invoke(invoker, parameters);
}
}
throw new MissingMethodException();
}
}
This extension method allows me to call methods like this:
anyInstance.InvokeInstanceMethod("MethodName", param1, param2, ...);
Because all types, excluding Object itself, are derived from Object, this method can be cal on any instance of any type.
Then I use this method:
object dict = dictionaryType.CreateInstance(); // The method CreateInstance() is also an extension
dict.InvokeInstanceMethod("Add", key, val);
There are a lot of workarounds for the missing support of enumerations in the Entity Framework 4.0. From all of them I like this one at most:
http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx?PageIndex=2#comments
This workaround allows you to use enums in your LINQ queries which is what i exactly need. However, I have a problem with this workaround. I get for every complex type I'm using a new partial autogenerated class.Therefore the code does not compile any more because I already have a wrapper class with this name in the same namespace which converts betwen the backed integer in the database and the enum in my POCO classes. If I make my wrapper a partial class, the code still does not compile as it now contains two properties with the same name "Value". The only possibility is to remove the Value property by hand everytime I generate the POCO classes because the DB model changed (which during the development phase happens very often).
Do you know how to prevent a partial class to be generated out of complex property everytime the EF model changes?
Can you recommend me some other workarounds supporting enumerations in LINQ queries?
That workaround is based on the fact that you are writing your POCO classes yourselves = no autogeneration. If you want to use it with autogeneration you must heavily modify T4 template itself.
Other workaround is wrapping enum conversion to custom extension methods.
public static IQueryable<MyEntity> FilterByMyEnum(this IQueryable<MyEntity> query, MyEnum enumValue)
{
int val = (int)enumValue;
return query.Where(e => e.MyEnumValue == val);
}
You will then call just:
var data = context.MyEntitites.FilterByMyEnum(MyEnum.SomeValue).ToList();
I am using an approach based on the one described in your link without any modifications of the T4 templates. The contents of my partial wrapper classes are as follows:
public partial class PriorityWrapper
{
public Priority EnumValue
{
get
{
return (Priority)Value;
}
set
{
Value = (int)value;
}
}
public static implicit operator PriorityWrapper(Priority value)
{
return new PriorityWrapper { EnumValue = value };
}
public static implicit operator Priority(PriorityWrapper value)
{
if (value == null)
return Priority.High;
else
return value.EnumValue;
}
}
I've only changed that instead of a back store variable with enum value I am using the autogenerated int typed Value property. Consequently Value can be an auto-implemented property and EnumValue property needs to do the conversion in getter and setter methods.
I have a function that returns objects of different types based on the parameter passed to this function.
Is it possible to add these different object types to a collection based on some identifier in C# 4.0?
Usually we do something like this
List or List
but i want one collection which can add object of any type.
Instead of just making a List<object> like other posters are recommending, you may want to define an interface eg IListableObject that contains a few methods that your objects need to implement. This will make any code using these objects much easier to write and will guard against unwanted objects getting into the collection down the line.
Yes, it is called object. Eg:
var objlist = new List<object>();
objlist.Add(1);
objlist.Add(true);
objlist.Add("hello");
You could use object[], List<object>, ArrayList, IEnumerable, ... but if those types have a common base type it would be better to stick to a strongly typed collection.
Really your collection should be as specific as you can make it. When you say
objects of different types
Do these objects have anything in common? Do they implement a common interface?
If so you you can specialise the list on that interface List<IMyInterface>
Otherwise List<object> will do what you want.
Update
No, not really.
I'm sorry but I'm going to question your design.
If you have a collection of different objects, how do you decide how to use one of the objects?
You're going to have a large switch statement switching on the type of the object, then you cast to a specific object and use it.
You also have have a similar switch statement in your factory method that creates the object.
One of the benefits of Object Orientation is that if you design your objects correctly then you don't need to do these large "If it's this object do this.Method(), if it's that object do that.OtherMethod()".
Can I ask, why are you putting different objects into the same collection? What's the benefit to you?
If you want a collection which can add objects of any type then List<object> is the most appropriate type.
Collections in earlier versions of C# (not generics) can contain any kind of objects. If they're value type, they will be boxed into object.
When you need to use them, you can just cast it to the original type.
You may use List<Type> to hold the type information, if that's what you want. And Type[], Hashtable, etc. are also fine. You can use typeof operator to get the type or use Object.GetType().
Also check out Dynamic type.
http://msdn.microsoft.com/en-us/library/dd264736.aspx
It will basically do the same thing.
My Suggestion:
public class ParamValue
{
object value = null;
public ParamValue(object val)
{
value = val;
}
public string AsString()
{
return value.ToString();
}
public int AsInt()
{
return int.Parse(value.ToString());
}
public int? AsNullableInt()
{
int n;
if (int.TryParse(value.ToString(), out n))
{
return n;
}
return null;
}
public bool AsBool()
{
return bool.Parse(value.ToString());
}
public bool? AsNullableBool()
{
bool b;
if (bool.TryParse(value.ToString(), out b))
{
return b;
}
return null;
}
}
public class Params
{
Dictionary<string, object> paramCol = new Dictionary<string, object>();
public void Add(string paramName, object value)
{
paramCol.Add(paramName, value);
}
public ParamValue this[string paramName]
{
get
{
object v;
if (paramCol.TryGetValue(paramName, out v))
{
return new ParamValue(v);
}
return null;
}
}
}
Use param class as a collectio to your values, you can convert the return to every type you want.
You could use a Tuple of Genric Types
public Tuple<T, T> MySuperMethod()
{
int number = 1;
string text = "Batman";
return new Tuple<int, string>(number, text);
}
The .NET Framework directly supports tuples with one to seven
elements. In addition, you can create tuples of eight or more elements
by nesting tuple objects in the Rest property of a Tuple object.
https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.100).aspx