How cast parent into child to call right function in C# - c#

I Work on c#/Code first
I've a Parent Class
abstract public class form_base {}
and severals differents childs class.
Here one of them
public class form_Frais : form_base {
}
I've a view with all form_base, but when i click on one, I open a common template.
I just need change the mapping according to child type in changing the controler/Function by an URL
Then In my form_base
I had this :
public T Cast<T>(object o)
{
return (T)o;
}
public dynamic converttt(Type LeTyp)
{
MethodInfo castMethod = GetType().GetMethod("Cast").MakeGenericMethod(new[] { LeTyp });
dynamic castedObject = castMethod.Invoke(Activator.CreateInstance(LeTyp), new object[] { this });
return castedObject;
}
I've split my project in 2 part (engine/Web) My classes are define in engine
My problem is to fill my list of all form_base in web part.
I use this function in controler part
public ActionResult demandeur()
{
object model;
model = new { formsList = (from f in CurrentDBContext.forms_base select f).ToList().getCardModel(false) };
}
return View("demandeur", model);
}
And In web I create extension methods (I won't see in engine part)
public static partial class extensions
{
public static List<formListItem> getCardModel(this List<form_base> items, bool envalidation)
{
List<formListItem> model = new List<formListItem>();
if (items != null && items.Count > 0)
{
foreach (var item in items)
{
Type LeTyp = item.GetType().BaseType;
dynamic castedObject = item.converttt(LeTyp);//Pb here not good type : System.Data.Entity.DynamicProxies.form_Frais_353DEAA5...' ne contient pas de définition pour 'getCardModel''
model.Add(castedObject.getCardModel(envalidation));
}
}
return model;
}
public static formListItem getCardModelBase(this form_base f)
{
formListItem model = new formListItem();
model.id = f.id;
model.libelle = f.title;
model.libelleType = f.formType.title;
model.libelleStatut = f.StatutInterneLibelle;
model.demandeur = f.demandeur.fullName;
model.idtype = f.formType.id;
return model;
}
public static formListItem getCardModel(this form_Frais form, bool envalidation)
{
formListItem model = ((form_base)form).getCardModelBase();
model.URL = "/forms/NoteFrais/InitForm"; //The good URL
model.envalidation = envalidation;
return model;
}
}
I try to put all in extension part like that:
public static T Cast<T>(object o)
{
return (T)o;
}
public static List<formListItem> getCardModel(this List<form_base> items, bool envalidation)
{
List<formListItem> model = new List<formListItem>();
if (items != null && items.Count > 0)
{
foreach (var item in items)
{
Type LeTyp = item.GetType().BaseType;
MethodInfo castMethod = item.GetType().BaseType.GetMethod("Cast").MakeGenericMethod(new[] { LeTyp });
dynamic castedObject = castMethod.Invoke(null, new object[] { item });
model.Add(castedObject.getCardModel(envalidation));
}
}
return model;
}
public static formListItem getCardModelBase(this form_base f)
{
formListItem model = new formListItem();
model.id = f.id;
model.libelle = f.title;
model.libelleType = f.formType.title;
model.libelleStatut = f.StatutInterneLibelle;
model.demandeur = f.demandeur.fullName;
model.idtype = f.formType.id;
return model;
}
But I've error in item.GetType().BaseType.GetMethod("Cast").MakeGenericMethod(new[] { LeTyp }); cause GetMethod("Cast") return null
All my research come from here
UPDATE
In resume, In first try, I've problem of type class return dynamicproxy...
And in static version, I can't find method Cast..
I try
MethodInfo[] methodInfos = LeTyp.GetMethods(BindingFlags.Public | BindingFlags.Static);
But My array is empty... then my problem in static version will be hwo save correctly my Case function??? and use it in extension method
UPDATE 3
I find the problem in static mode
I need tu put Cast function in note_frais class
and use it
Type LeTyp = item.GetType().BaseType;
//MethodInfo[] methodInfos = LeTyp.GetMethods(BindingFlags.Public | BindingFlags.Static);
MethodInfo MI = LeTyp.GetMethod("Cast");//<T>.getMethod(cast)
MI = MI.MakeGenericMethod(typeof(form_base));
dynamic t = MI.Invoke(null, new object[] { item });
model.Add(t.getCardModel(envalidation));
But now I've same pb in 2 parts :
//Pb here not good type : System.Data.Entity.DynamicProxies.form_Frais_353DEAA5...' ne contient pas de définition pour 'getCardModel''
Thanks for your help? I read lot of things but now I'm completly lost.

Instead of:
GetMethod("Cast")
...try this overload:
GetMethod("Cast", new Type[] { typeof(Object) })
More observations...
The Cast<T> method of class form_base is not static. (See above to get this one.)
The class form_base doesn't define any public static methods.
(Side note, I'm not sure why the class extensions is defined as partial.)
The Cast<T> method in class extensions is static, but is not an extension method.
To get this one, you can use this overload, on type extensions:
typeof(extensions).GetMethod("Cast", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Object) }, null)
If you did define the Cast<T> extension method in class extensions:
public static partial class extensions {
public static T Cast<T>(this form_base b, object o) {/*…*/}
}
...then you could get it with the same overload on type extensions, by modifying the types argument:
typeof(extensions).GetMethod("Cast", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(form_base), typeof(Object) }, null)

Finally... With a simple sample it's good
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ConsoleApp1
{
abstract public class form_base
{
public Guid Guid { get; set; }
}
public class form_Frais : form_base
{
public int MonInt { get; set; }
public static T Cast<T>(object o)
{
return (T)o;
}
}
public class form_Avoir : form_base
{
public int MonInt { get; set; }
public static T Cast<T>(object o)
{
return (T)o;
}
}
public static class extensions
{
public static int GetCardModel(this form_Avoir form)
{
return form.MonInt * 100;
}
public static int GetCardModel(this form_Frais form)
{
return form.MonInt * form.MonInt;
}
}
public class TOTO
{
public static int GetCardModel(form_Avoir form)
{
return form.MonInt * 100;
}
public static int GetCardModel(form_Frais form)
{
return form.MonInt * form.MonInt;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
form_Frais nf = new form_Frais();
nf.Guid = Guid.NewGuid();
nf.MonInt = 2;
List<form_base> lst = new List<form_base>();
//MethodInfo[] methodInfos = typeof(form_base).GetMethods(BindingFlags.Public | BindingFlags.Static);
lst.Add(nf);
form_Avoir av = new form_Avoir();
av.Guid = Guid.NewGuid();
av.MonInt = 5;
lst.Add(av);
foreach (dynamic f in lst)
{
Console.WriteLine(TOTO.GetCardModel(f)); // OK
//Type LeTyp = f.GetType();
//MethodInfo MI = LeTyp.GetMethod("Cast");//<T>.getMethod(cast)
//MI = MI.MakeGenericMethod(typeof(form_base));
//dynamic t = MI.Invoke(null, new object[] { f });
//Console.WriteLine(t.GetCardModel());// Error
}
}
}
}
My error was to thought that extension methods was include in object. In fact not. It seems but not really. I just change with a method with parameter instead of extension

Related

Pass generic type to Theory [duplicate]

In xUnit I can have a Theory test that uses generics in this form:
[Theory]
[MemberData(SomeScenario)]
public void TestMethod<T>(T myType)
{
Assert.Equal(typeof(double), typeof(T));
}
public static IEnumerable<object[]> SomeScenario()
{
yield return new object[] { 1.23D };
}
Which will give me the generic T parameter as double. Is it possible to use MemberData to specify the generic type parameter for a test with a signature like:
[Theory]
[MemberData(SomeTypeScenario)]
public void TestMethod<T>()
{
Assert.Equal(typeof(double), typeof(T));
}
If it is not possible with MemberData or any other provided attribute (which I'm suspecting that it isn't), is it possible to create an attribute for Xunit that can achieve this? Maybe something along the lines of specifying Types in the Scenarios method and using reflection in a similar manner to Jon Skeet's answer here: Generics in C#, using type of a variable as parameter
You can simply include Type as an input parameter instead. E.g.:
[Theory]
[MemberData(SomeTypeScenario)]
public void TestMethod(Type type) {
Assert.Equal(typeof(double), type);
}
public static IEnumerable<object[]> SomeScenario() {
yield return new object[] { typeof(double) };
}
There is no need to go with generics on xunit.
Edit (if you really need generics)
1) You need to subclass ITestMethod to persist generic method info, it also has to implement IXunitSerializable
// assuming namespace Contosco
public class GenericTestMethod : MarshalByRefObject, ITestMethod, IXunitSerializable
{
public IMethodInfo Method { get; set; }
public ITestClass TestClass { get; set; }
public ITypeInfo GenericArgument { get; set; }
/// <summary />
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public GenericTestMethod()
{
}
public GenericTestMethod(ITestClass #class, IMethodInfo method, ITypeInfo genericArgument)
{
this.Method = method;
this.TestClass = #class;
this.GenericArgument = genericArgument;
}
public void Serialize(IXunitSerializationInfo info)
{
info.AddValue("MethodName", (object) this.Method.Name, (Type) null);
info.AddValue("TestClass", (object) this.TestClass, (Type) null);
info.AddValue("GenericArgumentAssemblyName", GenericArgument.Assembly.Name);
info.AddValue("GenericArgumentTypeName", GenericArgument.Name);
}
public static Type GetType(string assemblyName, string typeName)
{
#if XUNIT_FRAMEWORK // This behavior is only for v2, and only done on the remote app domain side
if (assemblyName.EndsWith(ExecutionHelper.SubstitutionToken, StringComparison.OrdinalIgnoreCase))
assemblyName = assemblyName.Substring(0, assemblyName.Length - ExecutionHelper.SubstitutionToken.Length + 1) + ExecutionHelper.PlatformSuffix;
#endif
#if NET35 || NET452
// Support both long name ("assembly, version=x.x.x.x, etc.") and short name ("assembly")
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == assemblyName || a.GetName().Name == assemblyName);
if (assembly == null)
{
try
{
assembly = Assembly.Load(assemblyName);
}
catch { }
}
#else
System.Reflection.Assembly assembly = null;
try
{
// Make sure we only use the short form
var an = new AssemblyName(assemblyName);
assembly = System.Reflection.Assembly.Load(new AssemblyName { Name = an.Name, Version = an.Version });
}
catch { }
#endif
if (assembly == null)
return null;
return assembly.GetType(typeName);
}
public void Deserialize(IXunitSerializationInfo info)
{
this.TestClass = info.GetValue<ITestClass>("TestClass");
string assemblyName = info.GetValue<string>("GenericArgumentAssemblyName");
string typeName = info.GetValue<string>("GenericArgumentTypeName");
this.GenericArgument = Reflector.Wrap(GetType(assemblyName, typeName));
this.Method = this.TestClass.Class.GetMethod(info.GetValue<string>("MethodName"), true).MakeGenericMethod(GenericArgument);
}
}
2) You need to write your own discoverer for generic methods, it has to be subclass of IXunitTestCaseDiscoverer
// assuming namespace Contosco
public class GenericMethodDiscoverer : IXunitTestCaseDiscoverer
{
public GenericMethodDiscoverer(IMessageSink diagnosticMessageSink)
{
DiagnosticMessageSink = diagnosticMessageSink;
}
protected IMessageSink DiagnosticMessageSink { get; }
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions,
ITestMethod testMethod, IAttributeInfo factAttribute)
{
var result = new List<IXunitTestCase>();
var types = factAttribute.GetNamedArgument<Type[]>("Types");
foreach (var type in types)
{
var typeInfo = new ReflectionTypeInfo(type);
var genericMethodInfo = testMethod.Method.MakeGenericMethod(typeInfo);
var genericTestMethod = new GenericTestMethod(testMethod.TestClass, genericMethodInfo, typeInfo);
result.Add(
new XunitTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(),
genericTestMethod));
}
return result;
}
}
3) Finally you can make your attribute for generic methods and hook it to your custom discoverer by XunitTestCaseDiscoverer attribute
// assuming namespace Contosco
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("Contosco.GenericMethodDiscoverer", "Contosco")]
public sealed class GenericMethodAttribute : FactAttribute
{
public Type[] Types { get; private set; }
public GenericMethodAttribute(Type[] types)
{
Types = types;
}
}
Usage:
[GenericMethod(new Type[] { typeof(double), typeof(int) })]
public void TestGeneric<T>()
{
Assert.Equal(typeof(T), typeof(double));
}

Object reflection c#

I want to generate the right object with one code line and not a switch case because always when a new device is added I have to add a new line.
Is it possible to do that in one line without switch case?
public static Device GetDevice(Device.enumDevice TypeOfDevice, string alias)
{
// Create the Object with using reflection
switch (TypeOfDevice)
{
case Device.enumDevice.A34411:
return new A34411(string alias);
break;
case Device.enumDevice.N5744:
return new N5744(string alias);
break;
default:
throw new NotImplementedException();
}
return null;
}
You could store the factory methods as delegates in a dictionary
private static Dictionary<Device.enumDevice, Func<string, Device>> _factoryDict =
new Dictionary<Device.enumDevice, Func<string, Device>>{
[Device.enumDevice.A34411] = (alias) => new A34411(alias),
[Device.enumDevice.N5744] = (alias) => new N5744(alias),
};
...
public static Device GetDevice(Device.enumDevice TypeOfDevice, string alias)
{
if (_factoryDict.TryGetValue(TypeOfDevice, out var factory)) {
return factory(alias);
}
throw new NotImplementedException();
// No retun statement here, as it would be unreachable because of the throw statement.
}
Or, using reflection:
const string deviceNameSpace = "MyName.MyProject.Devices.";
public static Device GetDevice(Device.enumDevice deviceType, string alias)
{
string typeName = deviceNameSpace + deviceType.ToString();
Type type = Type.GetType(typeName, throwOnError: true);
return (Device)Activator.CreateInstance(type, alias);
}
An elegant approach would be to use Dependency Injection with "Named Type Registrations"
Fast, but not quite a complete example:
public abstract class Device
{
protected Device(string alias)
{
Alias = alias;
}
public string Alias { get; }
}
public class A1 : Device
{
public A1(string alias) : base(alias) { }
}
public class A2 : Device
{
public A2(string alias) : base(alias) { }
}
class DeviceAttribute : Attribute
{
public DeviceAttribute(Type type)
{
Type = type;
}
public Type Type { get; }
}
public enum DeviceEnum
{
[Device(typeof(A1))]
A1,
[Device(typeof(A2))]
A2
}
public static class DeviceEnumExtension
{
public static Device GetInstance(this DeviceEnum obj, string alias)
{
var member = typeof(DeviceEnum).GetMember(obj.ToString());
if (member[0].GetCustomAttributes(typeof(DeviceAttribute), false)[0] is DeviceAttribute deviceAttr)
{
var ctor = deviceAttr.Type.GetConstructor(new[] {typeof(string)});
return ctor.Invoke(new object[] {alias}) as Device;
}
return null;
}
}
public class UnitTest1
{
[Fact]
public void Test1()
{
// Arrange
var a1 = DeviceEnum.A1;
var a2 = DeviceEnum.A2;
// Act
var instanceA1 = a1.GetInstance("A1");
var instanceA2 = a2.GetInstance("A2");
// Assert
Assert.Equal(typeof(A1), instanceA1.GetType());
Assert.Equal(typeof(A2), instanceA2.GetType());
Assert.Equal("A1", instanceA1.Alias);
Assert.Equal("A2", instanceA2.Alias);
}
}

xUnit theory test using generics

In xUnit I can have a Theory test that uses generics in this form:
[Theory]
[MemberData(SomeScenario)]
public void TestMethod<T>(T myType)
{
Assert.Equal(typeof(double), typeof(T));
}
public static IEnumerable<object[]> SomeScenario()
{
yield return new object[] { 1.23D };
}
Which will give me the generic T parameter as double. Is it possible to use MemberData to specify the generic type parameter for a test with a signature like:
[Theory]
[MemberData(SomeTypeScenario)]
public void TestMethod<T>()
{
Assert.Equal(typeof(double), typeof(T));
}
If it is not possible with MemberData or any other provided attribute (which I'm suspecting that it isn't), is it possible to create an attribute for Xunit that can achieve this? Maybe something along the lines of specifying Types in the Scenarios method and using reflection in a similar manner to Jon Skeet's answer here: Generics in C#, using type of a variable as parameter
You can simply include Type as an input parameter instead. E.g.:
[Theory]
[MemberData(SomeTypeScenario)]
public void TestMethod(Type type) {
Assert.Equal(typeof(double), type);
}
public static IEnumerable<object[]> SomeScenario() {
yield return new object[] { typeof(double) };
}
There is no need to go with generics on xunit.
Edit (if you really need generics)
1) You need to subclass ITestMethod to persist generic method info, it also has to implement IXunitSerializable
// assuming namespace Contosco
public class GenericTestMethod : MarshalByRefObject, ITestMethod, IXunitSerializable
{
public IMethodInfo Method { get; set; }
public ITestClass TestClass { get; set; }
public ITypeInfo GenericArgument { get; set; }
/// <summary />
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public GenericTestMethod()
{
}
public GenericTestMethod(ITestClass #class, IMethodInfo method, ITypeInfo genericArgument)
{
this.Method = method;
this.TestClass = #class;
this.GenericArgument = genericArgument;
}
public void Serialize(IXunitSerializationInfo info)
{
info.AddValue("MethodName", (object) this.Method.Name, (Type) null);
info.AddValue("TestClass", (object) this.TestClass, (Type) null);
info.AddValue("GenericArgumentAssemblyName", GenericArgument.Assembly.Name);
info.AddValue("GenericArgumentTypeName", GenericArgument.Name);
}
public static Type GetType(string assemblyName, string typeName)
{
#if XUNIT_FRAMEWORK // This behavior is only for v2, and only done on the remote app domain side
if (assemblyName.EndsWith(ExecutionHelper.SubstitutionToken, StringComparison.OrdinalIgnoreCase))
assemblyName = assemblyName.Substring(0, assemblyName.Length - ExecutionHelper.SubstitutionToken.Length + 1) + ExecutionHelper.PlatformSuffix;
#endif
#if NET35 || NET452
// Support both long name ("assembly, version=x.x.x.x, etc.") and short name ("assembly")
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == assemblyName || a.GetName().Name == assemblyName);
if (assembly == null)
{
try
{
assembly = Assembly.Load(assemblyName);
}
catch { }
}
#else
System.Reflection.Assembly assembly = null;
try
{
// Make sure we only use the short form
var an = new AssemblyName(assemblyName);
assembly = System.Reflection.Assembly.Load(new AssemblyName { Name = an.Name, Version = an.Version });
}
catch { }
#endif
if (assembly == null)
return null;
return assembly.GetType(typeName);
}
public void Deserialize(IXunitSerializationInfo info)
{
this.TestClass = info.GetValue<ITestClass>("TestClass");
string assemblyName = info.GetValue<string>("GenericArgumentAssemblyName");
string typeName = info.GetValue<string>("GenericArgumentTypeName");
this.GenericArgument = Reflector.Wrap(GetType(assemblyName, typeName));
this.Method = this.TestClass.Class.GetMethod(info.GetValue<string>("MethodName"), true).MakeGenericMethod(GenericArgument);
}
}
2) You need to write your own discoverer for generic methods, it has to be subclass of IXunitTestCaseDiscoverer
// assuming namespace Contosco
public class GenericMethodDiscoverer : IXunitTestCaseDiscoverer
{
public GenericMethodDiscoverer(IMessageSink diagnosticMessageSink)
{
DiagnosticMessageSink = diagnosticMessageSink;
}
protected IMessageSink DiagnosticMessageSink { get; }
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions,
ITestMethod testMethod, IAttributeInfo factAttribute)
{
var result = new List<IXunitTestCase>();
var types = factAttribute.GetNamedArgument<Type[]>("Types");
foreach (var type in types)
{
var typeInfo = new ReflectionTypeInfo(type);
var genericMethodInfo = testMethod.Method.MakeGenericMethod(typeInfo);
var genericTestMethod = new GenericTestMethod(testMethod.TestClass, genericMethodInfo, typeInfo);
result.Add(
new XunitTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(),
genericTestMethod));
}
return result;
}
}
3) Finally you can make your attribute for generic methods and hook it to your custom discoverer by XunitTestCaseDiscoverer attribute
// assuming namespace Contosco
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("Contosco.GenericMethodDiscoverer", "Contosco")]
public sealed class GenericMethodAttribute : FactAttribute
{
public Type[] Types { get; private set; }
public GenericMethodAttribute(Type[] types)
{
Types = types;
}
}
Usage:
[GenericMethod(new Type[] { typeof(double), typeof(int) })]
public void TestGeneric<T>()
{
Assert.Equal(typeof(T), typeof(double));
}

C# - How to pass generic type with type of "this" class

I have a User class that has a GetQueryable method. Another method, Select(), calls GetQueryable(). I want to use the Select method without passing the type User to the Select method, because I have it in this but I can't use it.
Type type = this.GetType();
???
var x = this.GetQueryable< ??? >().ToList();
class Program
{
static void Main(string[] args)
{
var acc = new User();
acc.Select();
}
}
public partial class User
{
public DB_Test001Entities context;
public User()
{
context = new DB_Test001Entities();
}
public void Select()
{
Type type = this.GetType();
var x = this.GetQueryable< **???** >().ToList();
}
public IQueryable<TEntity> GetQueryable<TEntity>(List<string> includes = null) where TEntity : class
{
IQueryable<TEntity> items = context.Set<TEntity>();
if (includes != null && includes.Any())
includes.Where(i => i != null).ToList().ForEach(i => { items = items.Include(i); });
return items;
}
}
You can do it using reflection. The following sample works smoothly. In program you can use Clerk or Manager, just any instance derived from User to call Select. You can improve your program with this.
class Clerk : User { }
class Manager : User { }
internal class User
{
public User() { }
public string Name { get; set; }
public void Select()
{
var list = new List<string>() {"Jack", "Martin"};
Type thisType = GetType();
MethodInfo method = thisType.GetMethod("GetQueryable").MakeGenericMethod(thisType);
method.Invoke(this, new object[] {list});
}
public IQueryable<TEntity> GetQueryable<TEntity>(List<string> includes = null) where TEntity : User, new()
{
if(includes != null)
{
Console.WriteLine(typeof(TEntity));
var entity = new List<TEntity>(includes.Count);
entity.AddRange(includes.Select(item => new TEntity {Name = item}));
return entity.AsQueryable();
}
return null;
}
}
class Program
{
static void Main()
{
User usr = new Manager();
usr.Select();
}
}

C# - Class with List<> of other Classes

I have a class, that has several elements of normal types, like int, String, etc.
It also has several elements that are various lists of other classes, that could be empty or have 1 to many items.
I have a function that I call with a generic type of the parent class, and I want to analyze data that could be in the sub elements, without knowing the types.
I am getting the parent members with the following code:
var getProperty = System.Runtime.CompilerServices.
CallSite<Func<System.Runtime.CompilerServices.CallSite,
object, object>>
.Create(Microsoft.CSharp.RuntimeBinder.
Binder.GetMember(0, property.Name, thisObject.GetType(), new[]
{
Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0, null)
}));
var thisValue = getProperty.Target(getProperty, thisObject);
I get the value into the var thisValue. At this point if I determine the underlying type of thisValue is a type of list, how can I grab the type of the list contents?
Here is the actual function....I can't seem to get it formatted nicely.
public static bool ObjectIsLike<T>(this T thisObject, T compareObject, params object[] argumentsToExclude)
{
for (int counter = 0; counter < argumentsToExclude.Length - 1; counter++)
{
argumentsToExclude[counter] = argumentsToExclude[counter].ToString().ToUpper();
}
bool objectIsLike = true;
foreach (var property in thisObject.GetType().GetProperties())
{
string fieldName = property.Name;
if (!argumentsToExclude.Contains(fieldName.ToUpper()))
{
try
{
var getProperty = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, property.Name, thisObject.GetType(), new[] { Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0, null) }));
var thisValue = getProperty.Target(getProperty, thisObject);
getProperty = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, property.Name, compareObject.GetType(), new[] { Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0, null) }));
var compareValue = getProperty.Target(getProperty, compareObject);
if (!(compareValue == null && thisValue == null))
{
if (compareValue == null || thisValue == null)
objectIsLike = false;
else
if (compareValue.GetType().FullName.Contains("List"))
{
//Ignore Lists
}
else
if (!compareValue.Equals(thisValue))
{
objectIsLike = false;
}
}
}
catch
{
objectIsLike = false;
}
}
}
return objectIsLike;
}
would GetType() work for you?
class Program
{
static void Main(string[] args)
{
MyClass1 c1 = new MyClass1();
foreach (var s in c1.pp)
{
Console.WriteLine(s.GetType());
}
Console.Read();
}
}
public class MyClass1
{
public MyClass2 p;
public List<object> pp;
public MyClass1()
{
p = new MyClass2();
pp = new List<object>();
pp.Add(new MyClass2());
pp.Add(new MyClass3());
pp.Add(new MyClass4());
}
}
public class MyClass2
{
public List<object> ppp;
public MyClass2()
{
ppp = new List<object>();
ppp.Add(new MyClass3());
ppp.Add(new MyClass4());
}
}
public class MyClass3
{
public int v;
}
public class MyClass4
{
public int v;
}

Categories

Resources