I am having an issue with Reflection, which I can't seem to find a solution for.
I have the following simple interface :
public interface IDataProperty<T>
{
public T Value { get; set; }
public int BytesCount();
public byte[] Serialize();
}
the struct which implements the interface above :
public struct IntProperty : IDataPropery<int>
{
private int _value;
public int Value { get => _value; set => _value = value; }
public int BytesCount()
{
return 4;
}
public byte[] Serialize()
{
return BitConverter.GetBytes(_value);
}
public IntDataProperty(int value) { _value = value; }
}
and a simple class to hold the values :
public class ValuesContainer
{
public IntProperty prop1;
public IntProperty prop2;
}
I am trying to call the Serialize() method on both prop1 and prop2 in my Processor class,
with no luck so far... :
public class Processor
{
public void ProccesData<T>(out T result) where T : ValuesContainer, new()
{
result = new T();
List<FieldInfo> dataFields = new List<FieldInfo>();
result.GetType().GetFields().ToList().ForEach(field => {
if(field.FieldType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDataProperty<>)))
{
dataFields.Add(field);
}
});
MethodInfo serializeMI = typeof(IDataProperty<>).GetMethod("Serialize");
foreach(FieldInfo field in dataFields)
{
Console.WriteLine(field.Name);
serializeMI.Invoke(field,null);
}
}
}
Running the code at this point gives me the following error :
'Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.'
I am aware that I need to get somehow to the instance behind the field variable, but have no idea how to do it.
Does anyone know a good way of doing what i am trying to achieve using other methods, or only Reflection is the way to go, and if the latter - what solutions do I have ?
Thanks in advance to all of you.
After the great help #JeroenMostert provided in the comments , i have been able to solve the issue at its roots. As long as Jeroen haven't provided an answer to be accepted as correct , I will just show his solution , so this question gets marked as answered. Still, the benefit here goes to #JeroenMostert
internal class Program
{
static void Main(string[] args)
{
ValuesContainer container = new ValuesContainer();
Processor processor = new Processor();
processor.ProccesData(out container);
}
}
public interface IDataProperty<T>
{
public void Serialize();
}
public struct IntProperty : IDataProperty<int>
{
private int _value;
public int Value { get => _value; set => _value = value; }
public int BytesCount()
{
return 4;
}
public void Serialize()
{
Console.WriteLine("I have been invoked !" + this.GetHashCode());
}
}
public class ValuesContainer
{
public IntProperty prop1;
public IntProperty prop2;
}
public class Processor
{
public void ProccesData<T>(out T result) where T : ValuesContainer, new()
{
result = new T();
List<FieldInfo> dataFields = new List<FieldInfo>();
result.GetType().GetFields().ToList().ForEach(field => {
if (field.FieldType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDataProperty<>)))
{
dataFields.Add(field);
}
});
foreach (FieldInfo field in dataFields)
{
Console.WriteLine("Invoking 'Serialize' method on fieldName :" + field.Name);
field.GetValue(result).GetType().GetMethod("Serialize").Invoke(field.GetValue(result), null);
}
}
}
Related
I am wondering is it possible to 'spread' tuple's values in a way to properly match method arguments.
For example:
public (int, object) GetTuple() {
return (5, null);
}
public void ReceiveMultipleArguments(int a, object b) { ... }
The call of ReceiveMultipleArguments method like this:
ReceiveMultipleArguments(GetTuple());
will result in this error:
CS7036: There is no argument given that corresponds to the required formal parameter 'b' of 'Method1(int, object)'
The possible solution is to destructure tuple manually then provide each value as method argument, but is there a way to do it shorter, like spread operator that exists in javascript, for example?
C# is a strongly typed language, so you cannot pass tuple (which has its own class ValueTuple class).
So, you could just define overload for the method:
public void Test()
{
ReceiveMultipleArguments(GetTuple());
}
public (int, object) GetTuple()
{
return (5, null);
}
public void ReceiveMultipleArguments((int a, object b) #params) => ReceiveMultipleArguments(#params.a, #params.b);
public void ReceiveMultipleArguments(int a, object b) { ... }
You could change the signature of the method to support params of object elements. Then you could unpack the tuple into individual elements and use that as parameter.
public void Main()
{
var tuple = GetTuple();
var items = UnpackTuple(tuple).ToArray();
DoSomethingWith(items);
}
public void DoSomethingWith(params object[] data)
{
foreach (var d in data)
{
Console.WriteLine(d);
}
}
public IEnumerable<object> UnpackTuple(ITuple tuple)
{
for (var index = 0; index < tuple.Length; index++)
{
yield return tuple[index];
}
}
public ITuple GetTuple()
{
return Tuple.Create(5, "second", 2.489, 'G');
}
However, I would strongly advice you to move away from tuples if you need to move them around in your program. From experience, I have seen that this will lead to a messy code base that is hard to understand and change.
Instead, define classes for your tuples. Lets say you need to pass an object, let's say an apple, and a count for how many apples into some method. The class could be a generic class such as:
public class CountOf<T>
{
public CountOf(T value, int count)
{
this.Value = value;
this.Count = count;
}
public T Value { get; }
public int Count { get; set; }
}
Or non-generic, such as:
public class CountedObject
{
public CountedObject(object obj, int count)
{
this.Object = obj;
this.Count = count;
}
public object Object { get; }
public int Count { get; set; }
}
Use case:
public void Main()
{
var apple = new Apple();
var countedApples = new CountOf<Apple>(apple, 10);
DoSomethingWith(countedApples);
var countedObject = new CountedObject(apple, 10);
DoSomethingWith(countedObject);
}
public void DoSomethingWith(CountOf<Apple> countedApples)
{
// do something here
}
public void DoSomethingWith(CountedObject countedObject)
{
// do something here
}
public class Apple { }
public class CountOf<T>
{
public CountOf(T value, int count)
{
this.Value = value;
this.Count = count;
}
public T Value { get; }
public int Count { get; set; }
}
public class CountedObject
{
public CountedObject(object obj, int count)
{
this.Object = obj;
this.Count = count;
}
public object Object { get; }
public int Count { get; set; }
}
maybe this help you:
static void Main(string[] args)
{
ReceiveMultipleArguments(GetTuple());
Console.WriteLine();
}
public static (int, object) GetTuple()
{
return (5, null);
}
public static void ReceiveMultipleArguments((int, object) p)
{
Console.WriteLine(p.Item1);
Console.WriteLine(p.Item2);
}
I know casting is not inherently bad practice, but is it bad in this situation?
I have the following class hierarchy, and the cast at the end.
public class A<T>
{
public A(string name, T value)
{
Name = name;
Value = value;
}
public string Name { get; }
public T Value { get; }
}
public class B : A<double>
{
public B(string name, double value, string expression)
: base(name, value)
{
Expression = expression;
}
public string Expression { get; }
}
public class C
{
public C(A<double> a)
{
_a = a;
}
public string Name { get { return _a.Name; } }
public double Value { get { return _a.Value; } }
protected A<double> _a;
}
public class D : C
{
public D(B b) : base(b)
{
}
public string Expression { get { return ((B)_a).Expression; } }
}
The line in question:
public string Expression { get { return ((B)_a).Expression; } }
Yes this is bad practice; like all downcasting (sometimes necessary to be sure; but that doesn't make it good).
The following code will generate a runtime exception:
A<double> myA = new A<double>("Test", 1.0d);
D test = new D(myA);
var boom = test.Expression; //InvalidCastException
Whereas with a different structure that wouldn't even compile. For example, modifying D to take a B instead of an A<double>
Try this, make the C class generic
public class C<T> where T : A<double>
{
public C(T thing)
{
_thing = thing;
}
protected T _thing;
}
Then D can be an instance of C with a generic argument of B
public D : C<B>
{
Public string Expression { get {return _thing.Expression;}}
}
I'm on my phone so please forgive.sny formatting or typo issues
So I have got these 2 instance types "FirstType" and "SecondType" which inherit from the mother class "ContaBancaria". They both return text from different textboxes. Basically, they do the same thing, but I need 2 instances for 2 different list types (I probably don't think the list has anything to do with my question, so I'll proceed not to go in detail)
Here are the instances:
private FirstType AddTypeFirst()
{
return new FirstType(textBoxNumber.Text,
textBoxBalance.Text,
textBoxName.Text,
textBoxAddress.Text,
textBoxBirth.Text);
}
private SecondType AddTypeSecond()
{
return new SecondType(textBoxNumber.Text,
textBoxBalance.Text,
textBoxName.Text,
textBoxAddress.Text,
textBoxBirth.Text);
}
Is there a way to return these 2 instances with the same method type?
EDIT:
What I meant was to return these 2 different types of instances with 1 single method, for example:
private [type?] AddInstance()
{
return new [type*] textBoxNumber.Text, //* the type could be FirstType or SecondType
textBoxBalance.Text,
textBoxName.Text,
textBoxAddress.Text,
textBoxBirth.Text);
}
EDIT 2:
ContaBancaria looks like this:
abstract class ContaBancaria
{
public string number { get; set; }
public string balance { get; set; }
public Client data { get; set; }
}
And, since there's Client...
class Client
{
public string name;
public string address;
public string birth;
}
Hope you get me.
You can use generic method and derrived classes I think.
For example, you have two classes and you want to receive one of them. Those classes are named "FirstSon" and "SecondSon" and both of them are derrived from class "Father".
class Father
{
string myName;
public string MyName
{
get { return myName; }
set { myName = value; }
}
public Father()
{
myName = "John";
}
}
class FirstSon : Father
{
string mySecondName;
public string MySecondName
{
get { return mySecondName; }
set { mySecondName = value; }
}
public FirstSon()
{
mySecondName = "Bill";
}
}
class SecondSon : Father
{
int age;
public int Age
{
get { return age; }
set { age = value; }
}
string mySecondName;
public string MySecondName
{
get { return mySecondName; }
set { mySecondName = value; }
}
public SecondSon()
{
mySecondName = "Drake";
age = 21;
}
}
And you have method GetObject(). This method is generic. It receives type of class, then checks what type it has received and returnes the new object with the same type.
public static T GetObject<T>() where T: Father
{
var firstSon = new FirstSon();
var secondSon = new SecondSon();
if (firstSon.GetType() == typeof(T))
return (T)Convert.ChangeType(firstSon, typeof(T));
return (T)Convert.ChangeType(secondSon, typeof(T));
}
It uses method Convert.ChangeType(object value, Type conversonType) and allows you to convert your object to your type.
But I am not convinced that this is a good idea according to How do I make the return type of a method generic?
Assuming you want to return the proper type based on the list being added to, you will need to write your own generic Add function, and use Reflection to figure out the type:
public static class Ext {
public static void AddInstancia<T>(this List<T> aList) where T : class {
if (typeof(T) == typeof(FirstType))
aList.Add(AddTypeFirst() as T);
else
aList.Add(AddTypeSecond() as T);
}
}
I see no good reason to do this - after all, you know the type of the list, just call the correct function for that list...
Instead of using Reflection, you could also use dynamic if you add some functions to each sub-type:
public class FirstType : Parent {
public FirstType MakeChild() {
return new FirstType();
}
}
public class SecondType : Parent {
public SecondType MakeChild() {
return new SecondType();
}
}
public static class Static<T> where T : new() {
public static dynamic Value = new T();
}
public static class Ext {
public static void AddInstance<T>(this List<T> aList) where T : new() {
aList.Add(Static<T>.Value.MakeChild());
}
}
Which you can call like
var list1 = new List<FirstType>();
list1.AddInstance();
I have a function as below:
public var UpdateMapFetcher(int stationID, int typeID)
I need this function to return either string or int.
My return value is set as below
if (finaloutput == "System.String")
{
// param1[i] = Convert.ChangeType(typeID_New.ToString(), typeof(string));
returnvalue = returnvalue.ToString();
return returnvalue;
}
else if (finaloutput == "System.Int32")
{
int a=0;
a = Convert.ToInt32(returnvalue);
return a;
}
How to have either one data type as return value in dynamic environment.
My intuition tells me, that you are trying to convert string value to some type. In that case you can use:
public T UpdateMapFetcher<T>(int stationID)
{
//var someValue = "23";
return (T)Convert.ChangeType(someValue, typeof(T));
}
//then
var typed = UpdateMapFetcher<int>(6);
In case you don't know T, you can use mapping (0-int, 1-string, etc.):
public object UpdateMapFetcher(int stationID, int type)
{
var typeMap = new []{ typeof(int), typeof(string)};
//var someValue = "23";
return Convert.ChangeType(someValue, typeMap[type]);
}
//then
var untyped = UpdateMapFetcher(6, 0/*0 is int*/);
if (untyped.GetType() == typeof(int))
{ /*is int*/
}
Another solution is to use implicit conversions:
public class StringOrInt
{
private object value;
public ValueType Type { get; set; }
public static implicit operator StringOrInt(string value)
{
return new StringOrInt()
{
value = value,
Type = ValueType.String
};
}
public static implicit operator StringOrInt(int value)
{
return new StringOrInt()
{
value = value,
Type = ValueType.Int
};
}
public static implicit operator int(StringOrInt obj)
{
return (int)obj.value;
}
public static implicit operator string(StringOrInt obj)
{
return (string)obj.value;
}
}
public enum ValueType
{
String,
Int
}
And then (simplified):
public static StringOrInt UpdateMapFetcher(int stationID, int typeID)
{
if (typeID == 0)
return "Text";
return 23;
}
private static void Main(string[] args)
{
var result = UpdateMapFetcher(1, 1);
if (result.Type == ValueType.String) { }//can check before
int integer = result;//compiles, valid
string text = result;//compiles, fail at runtime, invalid cast
}
you can return an object. You'd have to subsequently check for types in your consuming method. I assume that won't be a problem in your usecase.
your method signature is therefore:
public object UpdateMapFetcher(int stationID, int typeID)
You also have the option of using the out keyword, which permits you to accept both into variables and check after the function has been called.
public void UpdateMapFetcher(int stationID, int typeID, out int intValue, out string strValue)
// or int return val and out string value
public int UpdateMapFetcher(int stationID, int typeID, out string strValue)
With the use appearing something like this:
int intVal;
string strVal;
UpdateMapFetcher(stationID, typeID, out intVal, out strVal);
if (strVal != null)
{
doSomethingWithString(strVal);
}
else
{
doSomethingWithInt(intVal);
}
Frankly, I would just return a Tuple, with string being non-null indicating string value to use, and null as indicator for int return
public Tuple<string, int> UpdateMapFetcher(int stationID, int typeID) {
if (finaloutput == "System.String")
{
// param1[i] = Convert.ChangeType(typeID_New.ToString(), typeof(string));
returnvalue = returnvalue.ToString();
return new Tuple<string, int>(returnvalue, 0);
}
else if (finaloutput == "System.Int32")
{
int a=0;
a = Convert.ToInt32(returnvalue);
return new Tuple<string, int>(null, a);
}
}
On consumer side
var rc = UpdateMapFetcher( .... );
if (rc.Item1 != null) {
// code to use string value
} else {
// code to use int value
}
I would choose to return an object of new class which might look like this:
class Result {
public string StringValue { get; }
public string Int32Value { get; }
public bool IsString { get; }
public bool IsInt32 { get; }
public Result(string value) {
StringValue = value;
IsString = true;
}
public Result(int value) {
Int32Value = value;
IsInt32 = true;
}
}
This way you can check which Type is it by using Isxxx property. You can also enhance this with validation in value geters. F. e., for string it might look like this:
public string StringValue {
get {
if (IsString)
return m_stringValue;
throw new InvalidOperationException("Value is not a string.");
}
}
You can't really do exactly that, but there are several ways to do more or less what you want. You'd probably be better off change the design a little though.
Two ideas:
Either change your code to use two different methods, and call each of them as needed instead.
..Or return an object, which you can cast however you like..
..Or, use a generic method with TypeDescriptor, like the following.
Note that we here convert the value to string first even if it was an int, since we can then use a common method ConvertFromString() to convert it to whatever type T was.
public T UpdateMapFetcher<T>(int stationID, int typeID) {
// To allow parsing to the generic type T:
var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
if(converter != null)
{
return (T)converter.ConvertFromString(returnvalue.ToString());
}
else
{
return default(T);
}
}
Usage:
var result = MyExtensions.UpdateMapFetcher<string>(1, 2);
or:
var result = MyExtensions.UpdateMapFetcher<int>(1, 2);
You can return Object and cast to type which you want.
public Object UpdateMapFetcher(int stationID, int typeID)
if (finaloutput == "System.String")
{
// param1[i] = Convert.ChangeType(typeID_New.ToString(), typeof(string));
returnvalue = returnvalue.ToString();
return returnvalue;
}
else if (finaloutput == "System.Int32")
{
int a=0;
a = Convert.ToInt32(returnvalue);
return a;
}
A type that can contain either one type or another is usually called (unsurprisingly) Either. It is a special case of a sum type, basically a discriminated union, tagged union, or disjoint union with exactly two cases (instead of an arbitrary number).
Unfortunately, there does not exist an implementation of an Either type in the standard libraries, but there are plenty of implementations to be found on Google, GitHub, and elsewhere … and porting one of the existing implementations from e.g. Haskell or Scala isn't that hard, either.
It looks a bit like this (forgive my code, I don't actually know C♯ that well):
using System;
abstract class Either<A, B>
{
public abstract bool IsLeft { get; }
public abstract bool IsRight { get; }
public abstract A Left { get; }
public abstract B Right { get; }
public abstract A LeftOrDefault { get; }
public abstract B RightOrDefault { get; }
public abstract void ForEach(Action<A> action);
public abstract void ForEach(Action<B> action);
public abstract void ForEach(Action<A> leftAction, Action<B> rightAction);
private sealed class L : Either<A, B>
{
private A Value { get; }
public override bool IsLeft => true;
public override bool IsRight => false;
public override A Left => Value;
public override B Right { get { throw new InvalidOperationException(); } }
public override A LeftOrDefault => Value;
public override B RightOrDefault => default(B);
public override void ForEach(Action<A> action) => action(Value);
public override void ForEach(Action<B> action) {}
public override void ForEach(Action<A> leftAction, Action<B> rightAction) => leftAction(Value);
internal L(A value) { Value = value; }
}
private sealed class R : Either<A, B>
{
private B Value { get; }
public override bool IsLeft => false;
public override bool IsRight => true;
public override A Left { get { throw new InvalidOperationException(); } }
public override B Right => Value;
public override A LeftOrDefault => default(A);
public override B RightOrDefault => Value;
public override void ForEach(Action<A> action) {}
public override void ForEach(Action<B> action) => action(Value);
public override void ForEach(Action<A> leftAction, Action<B> rightAction) => rightAction(Value);
internal R(B value) { Value = value; }
}
public static Either<A, B> MakeLeft(A value) => new L(value);
public static Either<A, B> MakeRight(B value) => new R(value);
}
And you'd use it like this:
static class Program
{
public static void Main()
{
var input = Console.ReadLine();
int intResult;
var result = int.TryParse(input, out intResult) ? Either<int, string>.MakeLeft(intResult) : Either<int, string>.MakeRight(input);
result.ForEach(r => Console.WriteLine("You passed me the integer one less than " + ++r), r => Console.WriteLine(r));
}
}
I need to design a data structure that holds different types of values (doubles, strings, datetimes, etc.). The list of types is dynamically created by user. Based on that list another list of values should be created.
Then this "record" of values is to be sent by WCF and stored in dynamically created db table. I'm starting with desiging this solution in c#. My current status is shown below. I'm not satisfied with my present solution, especially with factory and enums. Is there better way to do the things right?
Enum for my types:
public enum ValueType { Decimal, String, Boolean };
then interface:
public interface IValueType
{
object Data { get; }
string ToString();
ValueType? Type { get; }
}
base class:
public abstract class ValueType<T> : IValueType
{
protected T _Value;
public ValueType(T value)
{
_Value = value;
}
public object Data
{
get { return _Value; }
}
public ValueType? Type
{
get { return null; }
}
public T Value { get; private set; }
public override string ToString()
{
return _Value.ToString();
}
}
one of implementation:
public class DecimalValueType : ValueType<decimal>
{
public DecimalValueType( decimal val ) : base(val)
{}
public DecimalValueType(double val) : base((decimal)val)
{}
public DecimalValueType(int val) : base((decimal)val)
{}
}
then factory:
public static class ValueTypeFactory
{
private static Dictionary<ValueType, Type> dictValueType = new Dictionary<ValueType, Type>()
{
{ ValueType.Decimal, typeof(DecimalValueType) },
{ ValueType.String, typeof(StringValueType) },
{ ValueType.Boolean, typeof(BooleansValueType) }
};
private static Dictionary<Type, Type> dictSimple = new Dictionary<Type, Type>()
{
{ typeof(decimal), typeof(DecimalValueType) },
{ typeof(double), typeof(DecimalValueType) },
{ typeof(int), typeof(DecimalValueType) },
{ typeof(string), typeof(StringValueType) },
{ typeof(bool), typeof(BooleansValueType) }
};
public static IValueType MakeByValueType(ValueType type, params object[] initValues)
{
IValueType retObject = null;
if (dictValueType.ContainsKey(type) )
{
Type t = dictValueType[type];
retObject = (IValueType)Activator.CreateInstance(t,initValues);
}
return retObject;
}
public static IValueType MakeByType(params object[] initValues)
{
IValueType retObject = null;
if ( initValues.Length > 0 )
{
Type type = initValues[0].GetType();
if (dictSimple.ContainsKey(type))
{
Type t = dictSimple[type];
retObject = (IValueType)Activator.CreateInstance(t, initValues);
}
}
return retObject;
}
}
sample use:
List<IValueType> lista = new List<IValueType>();
lista.Add(new DecimalValueType(12));
lista.Add(new StringValueType("Test"));
lista.Add(new BooleansValueType(true));
lista.Add(ValueTypeFactory.MakeByValueType(ValueType.Decimal, 10.1));
lista.Add(ValueTypeFactory.MakeByType(5.12));
lista.Add(ValueTypeFactory.MakeByType("Test2"));
I would be happy with any advice.
Here is a simpler solution that covers the usages in your post and avoids the ValueType subclass noise:
public abstract class ValueType
{
public enum Types { Decimal, String, Boolean };
public abstract object Data { get; }
public abstract Types Type { get; }
private ValueType() {}
protected class TypedValueType<T> : ValueType
{
private Types type;
public TypedValueType(T value, Types type) : base()
{
this.Value = value;
this.type = type;
}
public override object Data { get { return this.Value; } }
public override Types Type { get { return this.type; } }
public T Value { get; private set; }
public override string ToString()
{
return this.Value.ToString();
}
}
public static implicit operator ValueType(decimal value) { return new TypedValueType<decimal>(value, Types.Decimal); }
public static implicit operator ValueType(double value) { return new TypedValueType<decimal>((decimal)value, Types.Decimal); }
public static implicit operator ValueType(int value) { return new TypedValueType<decimal>((decimal)value, Types.Decimal); }
public static implicit operator ValueType(string value) { return new TypedValueType<string>(value, Types.String); }
public static implicit operator ValueType(bool value) { return new TypedValueType<bool>(value, Types.Boolean); }
}
Sample usage:
public class Demo
{
public static void Main()
{
List<ValueType> lista = new List<ValueType>();
lista.Add(1);
lista.Add("Test");
lista.Add(true);
lista.Add(10.1);
lista.Add(5.12);
lista.Add("Test2");
foreach(var value in lista) Console.WriteLine(value.Data + " - " + value.Type.ToString());
Console.ReadKey();
}
}
Since it appears that you are wanting to restrict the types of values that can be contained, the nested TypedValueType class is marked protected and the ValueType constructor is marked private. Implicit operators are used to provide the "factory" logic for producing the appropriate typed TypeValueType subclasses for the values that are to be casted.
Here is the output from executing this as a console app:
1 - Decimal
Test - String
True - Boolean
10.1 - Decimal
5.12 - Decimal
Test2 - String