How to use GetPropertyValueSafely from CommonLibrary.NET? - c#

When using the CommonLibrary.Net, how does one use the GetPropertyValueSafely() function correctly?
I want to do something like this:
public static string APP_TITLE = ComLib.ReflectionHelper.GetPropertyValueSafely(Application.ProductName);
but I need to add a second parameter, and I don't understand enough yet to know what is asked for. Here is the syntax usage from the documentation file:
public static Object GetPropertyValueSafely(
Object obj,
PropertyInfo propInfo
)
This are the parameter requirements:
Parameters obj Type: System..::..Object Object whose property is to be retrieved.
propInfo Type: System.Reflection..::..PropertyInfo Property name.
So what do I put for object? I tried this, too:
public static string APP_TITLE;
ComLib.ReflectionHelper.GetPropertyValueSafely(APP_TITLE, Application.ProductName);
but that's not the answer either.
I also tried this:
public static string APP_TITLE = ComLib.Reflection.ReflectionUtils.GetPropertyValue((object)APP_TITLE, Application.ProductName).ToString();
...which compiles, but it throws a runtime type error from the library.
Thanks for the help (I'm just starting to get this stuff into my head).

Try something like this:
public static readonly string APP_TITLE = (string)ComLib.ReflectionHelper.GetPropertyValueSafely(new object(),
ComLib.Reflection.ReflectionUtils.GetProperty(typeof(Application), "ProductName"));
NB: Technically, passing new object() to the PropertyInfo's GetValue method should throw a TargetException. However, since this is a static property, it seems to work.

Related

Initialising a generic parameter in a generic class

Alright, I have a generic class. The basics are this:
public class GenericPrimitiveContainer<T> : IGetAndSetGenericValue
{
private T _value;
public T Value
{
get
{
return _value;
}
set
{
_value = value;
}
}
}
Fine enough. I also have a SetValue method in that class which takes an object and sets it to the value which uses this code:
PropertyInfo pi = this.GetType().GetProperty("Value");
pi.SetValue(this, o, null);
That's not all it does because it also checks the type of the object and the type of Value and compares them. If they are the same, o (the object) is assigned to Value. If they're not the same, a conversion is applied. I won't go into that because that's not where the problem is (famous last words I'm sure).
The problem is if Value is of type string. As I said before, I compare the types to see if they are the same. This is as follows ('o' being the object passed in):
Type t1 = Value.GetType();
Type t2 = o.GetType();
if (t1 == t2) ...
If T is int, no problem. If T is String, 'Value' is just 'null'. I can't do 'GetType' on it even to see if it's a String because it's just null.
I have tried, as a test, just getting rid of the checks and testing the set method in a situation where I know a string will be passed to the method. Value was still initially null, but it worked out okay and Value was assigned.
Now I know string is not a primitive and so will work a little differently to an int, but I'm not sure how to overcome this problem. I considered initialising _value to default(T), which didn't work. I also added a constructor to the class which did the same thing. That also didn't work.
I have also tried constraining the class with a 'where t : new()' but that doesn't work because String is not a "non-abstract type with a public parameterless constructor in order to use it as parameter 'T'".
So hopefully someone wiser can help me out on this one.
Your problem is that Value.GetType() doesn't do what you want. Here's a really short complete example:
using System;
static class Generic
{
public static string WhatIsT<T>(T value)
{
return $"T is {value.GetType().FullName}";
}
}
class Program
{
static void Main(string[] args)
{
int i = 5;
Console.WriteLine(Generic.WhatIsT(i));
string s = "hello";
Console.WriteLine(Generic.WhatIsT(s));
s = null;
Console.WriteLine(Generic.WhatIsT(s));
Console.ReadLine();
}
}
The first and second calls to WhatIsT will be fine, but there will be a null reference exception on the third.
If you really really really really need to know the exact name of the generic type you've been closed over - and please heed the caveats in the comments that this almost certainly isn't the right thing to be doing - simply use typeof(T), like this:
return $"T is {typeof(T).FullName}";
Result:
T is System.Int32
T is System.String
T is System.String
Remember, GetType needs an object. typeof just needs a compile time name, which includes type parameters.

Is there any way to pass an undefined object as parameter? c#

I have a method that works with a defined data object type, like this:
public static ItemEdificio JSONtoOBJECT(this string JSONstring)
{
return new JavaScriptSerializer().Deserialize<ItemEdificio>(JSONstring);
}
Is there any way to convert the "ItemEdificio" into something than actualy vary according to the object type?
Keep in mind that this is made using the Newtonsoft library.
public static T JSONtoOBJECT<T>(this string JSONstring)
{
return new JavaScriptSerializer().Deserialize<T>(JSONstring);
}
Thats what generics (https://msdn.microsoft.com/en-us/library/0x6a29h6.aspx) are for.
You call it like this: MyType instance = jsonData.JSONtoOBJECT<MyType>();

Generic extension method refactor

I'm wondering if the following can be refactored in the way I would like it:
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ListExtensions
{
public static PaginatedList<Y> ToMappedPaginatedList<T, Y>(this PaginatedList<T> source)
{
var mappedList = new List<Y>();
Mapper.Map(source, mappedList);
return new PaginatedList<Y>(mappedList, source.PageIndex, source.PageSize, source.TotalCount);
}
}
The Mapper.Map line is using AutoMapper to map properties from an entity to a DTO object.
This is called like this:
var list = await _service.GetAllAsync(pageIndex, _pageSize);
var dtoList = list.ToMappedPaginatedList<Farmer, FarmerDTO>();
but I'd like to call it like this:
var dtoList = list.ToMappedPaginatedList<FarmerDTO>();
This saves a little bit of typing and you don't always need to be aware of the source list its type. Unfortunately this code doesn't work and I'm not sure if there's a simple answer.
Anyone got an idea?
Thanks in advance.
Yannick
If you have access to the PaginatedList class, putting the method in there will enable the syntax you desire since the instance knows what it's own type is.
I don't recommend the following but it demonstrates a way to take advantage of type inference.
You can enable type inference by adding a 2nd "useless" parameter of type Y.
If you pass default(FarmerDTO) as the 2nd parameter, a null will be passed as the parameter value but the intended type will be inferred.
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ListExtensions
{
public static PaginatedList<Y> ToMappedPaginatedList<T, Y>(this PaginatedList<T> source, Y destinationPlaceholder)
{
var mappedList = new List<Y>();
Mapper.Map(source, mappedList);
return new PaginatedList<Y>(mappedList, source.PageIndex, source.PageSize, source.TotalCount);
}
}
Call it like this:
var result1 = s.ToMappedPaginatedList(default(FarmerDTO));
Fair warning. I've never used this because I find the resulting code to be non-obvious as to what it is doing.
Either you call a method and specify all the generic arguments or you specify none and let the compiler infer them, there's no support for partial inference.
As such, the only way to get your code to compile is to make ToMappedPaginatedList take 1 generic parameter, instead of two.

Use classes static method when you only have the type name of the class as a string

I am wondering if it is possible to use a classes method when you only know the classes name by it's string value.
Let's say I have a class and within class I have a static method like
public class SomeClass
{
public static string Do()
{
//Do stuff
}
}
And when using class I want to something like
string str = (GetType(SomeClass)).Do();
When using the method I want to give the name of the class as string like I want to give SomeClass as a string.
var t = Type.GetType("MyNamespace.SomeClass");
var m = t.GetMethod("Do");
m.Invoke(null, new object[] { /* Any arguments go here */ });
You're going to have to use reflection throughout; for example:
object result = Type.GetType(typeName).GetMethod(methodName).Invoke(null, args);
Use Type.GetMethod to get the method info object of the method, then call MethodInfo.Invoke to execute it. For static methods, pass null as the first parameter (the object value):
Type type = typeof(SomeClass);
type.GetMethod("Do").Invoke(null, null);
If you don’t know the class name at compile time, you can also use object.GetType, Type.GetType or Assembly.GetType to get the type object at runtime (depending on what information you have available). Then, you can use it in the same way:
Type type = someObject.GetType(); // or Type.GetType("SomeTypeName");
type.GetMethod("Do").Invoke(null, null);
To be on the safe side, make sure to check whether GetMethod actually returns a method, so you have some confirmation that the method exists on that type then.

Why do I get a RuntimeBinderException using json.net with dynamic when calling a method

Why is it that when I use dynamic with json.net I get a runtime binding exception then calling a method without casting but I can do assignments not problem
private static void Main()
{
dynamic json = JObject.Parse("{\"Test\":23}");
var t = json.Test;
int a = t; //Success
Prop = t; //Success
Func(t); //RuntimeBinderException
}
private static void Func(int i){}
private static int Prop { get; set; }
When I cast it to the correct type there are no errors but I would prefer to not have to do that. Am I doing something wrong, is this a problem in the json.net library or is a language restriction.
Edit:
This is to solve a problem where I don't have control over the methods signature and I don't want to cast it on every call.
This is because json.Test returns a JValue and JValue has a dynamic TryConvert. So if you do an implicit static conversion by pointing it to an int or cast to an int it will at runtime call that TryConvert and you have success. However if you use that dynamically typed variable in a method argument, the c# runtime looks for a method named Func with an argument that best matches 'JValue' it will not try to call 'TryConvert' for every permutation of a possible method (even if it's only one) thus you get the runtime binding error.
So the simplest solution is to just cast on every call or set a statically typed variable each time you want to pass a JValue as an argument.
There is actually a more general question and answer of this same issue too if you are looking for more info:
Pass a dynamic variable in a static parameter of a method in C# 4
private static void Func(dynamic i){}
will solve the issue.

Categories