There have two dll's namely
a) lib1
b) lib2
These two library are loaded using reflection( as against to adding a direct reference in visual studio). I'm creating an object of a class , then want to type cast that object to the type of the interface (interface being in the dll loaded in the main program). I get an error saying type mismatch. Any possible solution to this problem.
Here is my code block:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Interfaceconversion
{
class Program
{
public static object classobj;
public static object interfaceobj;
static void Main(string[] args)
{
// Loading assembley 1
Assembly assembly1 = Assembly.LoadFrom(#"D:\WCFService\Aug9\Interfaceconversion\Lib1\bin\Debug\Lib1.dll");
Type[] type1 = assembly1.GetTypes();
foreach (Type item in type1)
{
if (item.FullName.ToString() == "Lib1.Class1")
{
classobj = Activator.CreateInstance(item);
}
}
// Loading assembly 2
Assembly assembly2 = Assembly.LoadFrom(#"D:\WCFService\Aug9\Interfaceconversion\Lib2\bin\Debug\Lib2.dll");
Type[] type2 = assembly2.GetTypes();
Type libtype = type2[1];
foreach (Type item in type2)
{
if (item.FullName.ToString() == "Lib2.Ilib2Interface1")
{
TODO: cast the object "classobj " to type Lib2.Ilib2Interface1
interfaceobj = classobj as item ;
}
}
#region old code
}
}
Lib2 dll's code is :
lib2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lib2
{
interface Ilib2Interface1
{
void lib2disp1();
}
}
Lib1 code is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lib1
{
interface ISttutil
{
void displayutil1();
void displayutil2();
}
interface Isttinterface
{
void displayinterface1();
void displayinterface2();
}
}
We don't see lib1.Class1 in the example given, but provided it derives from the interface you want to cast it to, something like this should work:
lib1:
using lib2;
using System;
namespace lib1
{
public class Class1 : IInterface1
{
public void MethodOne ( )
{
Console.WriteLine ( "MethodOne called!" );
}
}
}
lib2:
namespace lib2
{
public interface IInterface1
{
void MethodOne ( );
}
}
Main:
using lib2;
using System;
using System.IO;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main ( string [ ] args )
{
var fileInfo = new FileInfo ( #".\lib1.dll" );
var assembly = Assembly.LoadFile ( fileInfo.FullName );
var obj = assembly.CreateInstance ( "lib1.Class1" ) as IInterface1;
if ( obj != null ) obj.MethodOne ( );
Console.ReadLine ( );
}
}
}
Related
The error I got :
"object" doesn't contain a definition for "test"
I also tried game.test() but I keep getting this error
This solution is divided in two distinct projects :
The first one is a .dll
The second one is a console
the goal is to call the get method from the 'iw4mp' class dynamicaly. So I would be able to call any from the class while it will be loaded.
the COD class should look useless but in the futur it will look if the process is running on the computer but for my test I use a string (but it actually work same way as if it was looking for a process).
Code from the DLL
COD
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CODOffsets.Interface;
using CODOffsets.Offsets;
namespace CODOffsets
{
public class COD
{
static string[] games = { "iw4mp", "iw5mp", "bo1" };
static Type CallofDuty;
public static bool checkGame()
{
foreach (string game in games)
{
if (ProcessHandle(game))
{
CallofDuty = Type.GetType("CODOffsets.Offsets" + "." + game);
return true;
}
}
return false;
}
public static object Game()
{
return Activator.CreateInstance(CallofDuty) as ICODClass;
}
public static bool ProcessHandle(string game)
{
if (game == "iw4mp")
return true;
else
return false;
}
}
}
Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CODOffsets.Interface
{
interface ICODClass
{
string test { get; }
}
}
Offset
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CODOffsets.Interface;
namespace CODOffsets.Offsets
{
class iw4mp : ICODClass
{
public string test { get { return "this is mw2"; } }
}
}
Code from the Console project
Main
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CODOffsets;
namespace TestGenericClass
{
class Program
{
static void Main(string[] args)
{
if (COD.checkGame())
{
dynamic game = COD.Game();
Console.WriteLine(game.test);
Console.ReadKey();
}
}
}
}
It should basically work as the way you did. But, if not so, here are some alternatives.
you can use reflections in c# to get all the properties of the dynamic object.
var nameOfProperty = "test";
var propertyInfo = game.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(game, null);
Moreover, you can simply use this way to get the value if you know the property name
string value = game["test"];
Below is code fragments
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace DetailTest
{
class Program
{
static void Main(string[] args)
{
A a = new A();
PropertyInfo pi = a.GetType().GetProperty("cs");
MemberInfo[] mis = pi.PropertyType.GetMembers();
MemberInfo[] mis2 = mis.Where(d => d.Name.StartsWith("A")).ToArray();
foreach (MemberInfo mi in mis2)
{
Console.WriteLine(mi);
}
}
}
class A
{
B _b = new B();
public B b { get{return _b;}}
public List<C> cs{get;set;}
}
}
I just want to get Any method, but I got nothing. Why?
I mean how to get Any method of List type?
ps: I really reference System.Linq
Apologies if this sounds complex my vocab isn't fully with me today.
I have an method where I want to use .click
Example
middle.click();
But I also have another
end.click();
What if I want to pass either "middle" or "end" as a parameter, is it possible to do so
MethodGo(string usedforSomethingElse, Func<string> thisMethod)
{
thisMethod.click();
}
It would have to look more like this:
MethodGo(string usedforSomethingElse, ISomeObjectWithClickMethod thisObject)
{
thisObject.click();
}
Or, you could do this:
MethodGo(string usedforSomethingElse, Func<string> thisMethod)
{
thisMethod();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Student
{
public interface IMyClick
{
string click();
}
}
--------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Student
{
public class Middle : IMyClick
{
public string click()
{
return "Middle Click";
}
}
}
---------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Student
{
public class End :IMyClick
{
public string click()
{
return "End Click";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Student;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
IMyClick m1 = new Middle();
IMyClick e1 = new End();
string result = MethodtoGo(m1);
Console.WriteLine(result);
Console.Read();
}
static string MethodtoGo(IMyClick cc)
{
return cc.click();
}
}
}
in the above code now you can pass the Middle or End class instance as both are implementing the same interface.
string result = MethodtoGo(m1);
The MethodToGo has one parameter of type interface, that mean any class that is implementing the interface can be pass as input to the method.
hope this helps.
Here is the code:
interface IA
{
}
interface IC<T>
{
}
class A : IA
{
}
class CA : IC<A>
{
}
class Program
{
static void Main(string[] args)
{
IA a;
a = (IA)new A(); // <~~~ No exception here
IC<IA> ica;
ica = (IC<IA>)(new CA()); // <~~~ Runtime exception: Unable to cast object of type 'MyApp.CA' to type 'MyApp.IC`1[MyApp.IA]'.
}
}
Why am I getting the casting exception in the last line of the code ?
You need to declare IC as interface IC<out T> for the cast to work. This tells the compiler that IC<A> can be assigned to a variable of type IC<IA>.
See, this page for an explanation.
you can do
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
interface IPerson
{
}
//Have to declare T as out
interface ICrazy<out T>
{
}
class GTFan : IPerson
{
}
class CrazyOldDude : ICrazy<GTFan>
{
}
class Program
{
static void Main(string[] args) {
IPerson someone;
someone = (IPerson)new GTFan(); // <~~~ No exception here
ICrazy<GTFan> crazyGTFanatic;
ICrazy<IPerson> crazyPerson;
crazyGTFanatic = new CrazyOldDude() as ICrazy<GTFan>;
crazyGTFanatic = (ICrazy<GTFan>)(new CrazyOldDude());
crazyPerson = (ICrazy<IPerson>)crazyGTFanatic;
}
}
}
I have a little console application that I'm tinkering with just to learn something new.
In the code below, in Console.WirteLine(), if I test t.IsAbstract, or t.IsSealed, my output is AbstractClass true, or SealedClass true respectively. All others return false as I expect.
However, if I test t.IsPublic, everything, including both PublicClass and PublicInterface return false. Why is that?
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ConsoleApplication1
{
class Test
{
static void Main(string[] args)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] assemblyTypes = assembly.GetTypes();
foreach (Type t in assemblyTypes)
Console.WriteLine(t.Name + " " + t.IsPublic);
Console.ReadKey();
}
private class PrivateClass { }
public class PublicClass { }
protected class ProtectedClass { }
sealed class SealedClass { }
abstract class AbstractClass { }
interface myInterface { }
public interface PublicInterface { }
}
}
Because they are nested inside of Test.
From the documentation: true if the Type is declared public and is not a nested type; otherwise, false.
As #Jeb's answer and the docs suggest, typeof(PublicClass) should have a value of true for the IsNestedPublic property
It's not public outside the assembly...IsNestedPublic should be true though..