Casting a ValueTuple from a cached object - c#

When I am checking my cache to see if if my ValueTuple is in the cache, I use the code below. In this scenario, the value coming back is null (aka does not exist in the cache). When the code runs I get object not set to instance of an object error on the 1st line. Is there a proper way to cast an object to a ValueTuple?
var geo = ((double, double))CacheEngine.Get(key);
if (!geo.Equals(default(ValueTuple<double, double>))) return geo;

I found that I needed to do it like this to work. You need to cast to ValueTuple<double, double> and not (double, double).
var geo = CacheEngine.Get(key);
if (geo != null)
{
var geoTuple = (ValueTuple<double, double>)geo;
if (!geoTuple.Equals(default(ValueTuple<double, double>)))
return geoTuple;
}

Related

How to cast an object to a generic type

I have a Mock list like this.
var MockList = new List<Mock>() {
new Mock<IBikeRepository>(MockBehavior.Strict),
new Mock<IGreeterService>(MockBehavior.Strict)
};
Now I get back one object like this.
var greeterServiceMock = this.MockList
.FirstOrDefault(mock => typeof(Mock<IGreeterService>) == mock.GetType());
Since MockList is of the type List<Mock>, the object that I pulled out from the list this.MockList is of the type Mock. But I can see the runtime type is Mock<IGreeterService>
Now I have to cast it to Mock<IGreeterService>
Is there a way here?
Edit
I think I got it.
var t = (Mock<IGreeterService>)greeterServiceMock!;
The ! at the end was the key. It was giving error without it and so I had to put the question here.
The reason you still need to cast is that FirstOrDefault will return a reference of the type of the list. You can filter ans cast at the same time by using OfType:
this.MockList.OfType<Mock<IGreeterService>>().FirstOrDefault();

How to use variable type in as operator

For example:I have 2 variable (value ) & (property) i want to check is cast possible for value? We do not know the type of variables, How to check if cast is possible?
var value = Reader[item];
PropertyInfo property = properties.Where(x => x.Name == item).FirstOrDefault();
var type=property.PropertyType;//Or property.ReflectedType
var cs= value as type // Error: type is variable but is used like a Type
if (cs!=null){
...
}
Sample 1:
var value = 123;//is int
type = property.GetType();// is double
var x = (double)value;//Can be casted
Sample 2:
var value = "asd";//is string
type = property.GetType();// is double
var x = (double)value;//Can not be casted
You can use IsAssignable:
bool isValidCast = type.IsAssignableFrom(value.GetType())
As per the comments about int to double:
I've made a mistake in my comment, so i deleted it.
int can be implicitly converted to double because there is a predefined implicit conversion, see here
There are many ways to convert or cast from type to type. For example, You can use implicit/explicit conversion, you can use TypeConverter or implement the IConvertible interface.
Now, you have to decide which use case is relevant to you. It can be a bit complex to check them all, especially without knowing the destination type at design time.
In your code snippet, type is a variable of type Type, hence why it is throwing that error. You can change your code to use Convert.ChangeType() instead. Something like this:
var value = Reader[item];
PropertyInfo property = properties.Where(x => x.Name == item).FirstOrDefault();
var type=property.PropertyType;
object cs= Convert.ChangeType(value, type);
if (cs!=null){
...
}
Notice that, since you don't know the strong type of your property at compile time, you still have to box it into an object type after changing its type. This means you wouldn't be able to access its properties and methods directly using dot syntax in code (e.g. cs.MyProperty). If you wish to be able to do that, you can use the dynamic type in C#:
dynamic dcs = cs;
Console.Write(dcs.MyProperty);
When using Convert.ChangeType() you have to make sure you are converting to the correct type. E.g.:
if (value.GetType() == type)
{
object cs= Convert.ChangeType(value, type);
}

Object does not match target type PropertyInfo SetValue - one class to another

So I have 2 classes, both have identical Property names. One class contains different variables: int, strings, bool and DateTime The second class contains only 1 int and the rest are all strings.
Now I want to loop through all the properties, get the value from class1, encrypt that data and save it as a string in obj2, then return it to the main form (to save it in a database later).
public PersoonEncrypted EncryptPersonClass(Class1 object1)
{
PersoonEncrypted persEncrypt = new PersoonEncrypted(); //second class obj
Type type = object1.GetType();
PropertyInfo[] properties = type.GetProperties();
Type type2 = persEncrypt.GetType();
PropertyInfo[] properties2 = type.GetProperties();
foreach (var bothProperties in properties.Zip(properties2, (obj1, obj2) => new { Obj1 = obj1, Obj2 = obj2 }))
{
string value = "";
value = bothProperties.Obj1.GetValue(object1) as string;
if (!string.IsNullOrWhiteSpace(value))
{
string encryptValue = Encrypt(value);
if ((bothProperties.Obj2 != null) && (bothProperties.Obj2.PropertyType == typeof(string)))
{ //!= null check has no effect at all
bothProperties.Obj2.SetValue(persEncrypt, encryptValue, null); //errorLine
}
}
}
return persEncrypt;
}
That is what I came up with until now.
I have, of course, searched for other solutions like this one. This, after applying some own changes, didn't return any errors, but it didn't save any encrypted strings into the class persEncrypt. What I concluded was, from that test, is that it was testing if the value in the second class(persEncrypt in my example) from the particular property was null, while it shouldn't do that, it should make a new instance of that variable and save it in the object class, but removing that check gave me the same error.
you're just .Zip-ing the two lists of PropertyInfo objects, which simply iterates through both lists and doesn't check or sort for any sort of matching. This could result in erroneous behavior depending on the order in which properties appear - consider using a .Join instead to match property names.
This code doesn't check for an indexer on the property before attempting to assign to it without one - any indexed property which is of type string will make it to this point and then throw an exception when you try to set it.
Because this code is calling into Properties, there's the possibility an exception is being thrown by the code of the Property itself. This is where a StackTrace from your exception could reveal much more about what's happening.
Your code also checks for a property of type string directly - when using reflection you should use IsAssignableFrom instead in order to allow for inherited types, though that is unlikely the issue in this one case.

How to get value in object type list C#

I have a System.object type list.
I can't use [0] or [1],... to get value because it is object.
I tried GetType() and use many functions, but didn't work.
Is there any way to read it?
I write a function can convert any object, convert means validate or something.
private static IDictionary<string, object> objectConvert(object data)
{
var result = new Dictionary<string, object>();
var attrs = data.GetType().GetProperties();
foreach (var attr in attrs)
{
// if attribute is object do something (use use recursion )...
// if attribute is list do something (use recursion)...
// if not object or list, just add to result
// after all return result
}
}
Attribute is object I work well, but when it is list I tried so hard but can't get any element in list object.
You can cast it. Use as so that it is null if the cast fails and check it:
var list = yourObjectInstance as IList<type_here>();
if (list != null) {
// cast successful.
}
If you know the actual type of your object, simply cast it to that type using standard casting. You can then use indexer on it like ((List<T>)YourObject)[0].

Get PropertyInfo value

I'm trying to get the value from a PropertyInfo[], but I can't get it to work:
foreach (var propertyInfo in foo.GetType().GetProperties())
{
var value = propertyInfo.GetValue(this, null);
}
Exception: Object does not match target type.
Isn't this how it's supposed to be done?
You're trying to get properties from this when you originally fetched the PropertyInfos from foo.GetType(). So this would be more appropriate:
var value = propertyInfo.GetValue(foo, null);
That's assuming you want to effectively get foo.SomeProperty etc.
You're getting that exception because this isn't the same type as foo.
You should make sure you're getting the properties for the same object that you're going to try to get the value from. I'm guessing from your code that you're expecting this to be foo inside the scope of the loop (which isn't the case at all), so you need to change the offending line to:
var value = propertyInfo.GetValue(foo, null);
You are processing properties declared in foo's type, but try to read their values from this, which apparently isn't of the same type.

Categories

Resources