I want to know whether passed object is actually reference of variable of specific class or not.
Consider below structure of some class 'ClassA':
public classA
{
string variable1;
int variable2;
method1(ref variable1);
}
Now if in class that contains implementation of method1(Obj object1), I want to check that 'object1' is which variable of specific 'ClassA' ?
Because I want to check in if condition like if object1 is variable1 of ClassA then //to proceed with logic....
Please provide a small example for the same.
The closest you could get to this in safe code is using expressions, but honestly you probably don't want to do this. It'd be a nightmare to try and debug, and there's probably another way to go about it. For example, is there any reason variable1 can't be of a specific type?
Now that I've spoken reason, the approach using expressions goes something like this (This is from a debugging helper, I would never use this approach in anything remotely serious. Note: A lot of exception handling and other code is stripped from this, also note how ugly and hackish it looks, that's all why you really shouldn't do this):
public static void DoStuffWithParameter<T>(Expression<Func<T>> paramExpression)
{
if (paramExpression == null) throw new ArgumentNullException("paramExpression");
var body = ((MemberExpression)paramExpression.Body);
var paramName = body.Member.Name;
var param = ((FieldInfo)body.Member)
.GetValue(((ConstantExpression)body.Expression).Value);
var declaringType = param.DeclaringType;
var paramValue = paramExpression
.Compile()
.Invoke();
if(declaringType.Equals(typeof(ClassA)))
{
//do stuff
}
}
To use that you'd use something like:
DoStuffWithParameter(()=>myClass.VarA);
I found solution. The simplest way to do this is to pass object of sender in method1 and proceed, like below.
method1(Object sender, ref Object var)
{
if(sender is classA)
{
classA senderObj= (classA) sender;
if((string)var == senderObj.variable1)
{
// Logic for variable1
}
else if((int)var == senderObj.variable2)
{
// Logic for variable2
}
. . .
}
}
Related
I'm generating a random number from 1-1000. I have 200 functions named function1, function4, function 10, function 11, etc. What I would like to do is execute a specific function depending on if the number generated requires a function, and ignore it if not.
My first thought was to create an int[] containing all of the values that would trigger a function, and if the int[] contains the random number to use if statements to figure out what the number is. I'm concerned that it must be a really crude solution to an easy problem though.
I know the "best way" to do something is subjective, but is there a better way to accomplish this?
UPDATE: As per comments, I should probably have started out by pointing out that doing this for 200 functions is probably a good sign that there is some serious issue in your design. This is probably an XY question where you are trying to solve a problem in some crazy way and asking about your intended solution instead of asking about the problem itself.
That said I'll leave the original answer because it's still good advice when mapping a reasonable amount of function calls that can/will change during the life cylce of your app or dynamically as the code runs.
I won't get into why you are doing this, but I'll try to at least point you in the right direction so this doesn't become a complete nightmare when you need to modify/expand behavior:
You can map numbers to function calls using delegates and a dictionary. Assuming your functions take no arguments and return void you'd do:
var functionsMap = new Dictionary<int, Action>();
//map functions
var r = getSomeRandomNumber();
if (functions.TryGetValue(r), out var a)
a(); //invoke function
Mapping functions is simply adding keys and values:
functionsMap.Add(1, () => function1());
functionsMap.Add(3, () => function3());
//etc.
If your functions take arguments or return values, you'd use the adequate delegate: Action<T>, Func<T1, T2> etc.
You can use reflection to invoke appropriate method:
Type exampleType = exampleObject.GetType();
MethodInfo exampleMethod = exampleType.GetMethod(methodName);
exampleMethod.Invoke(this, null);
Where methodName can be created using your random number.
Without commenting on the wisdom of having 200 functions named the way yours are, you can use reflection to determine whether a given functionX() exists, like so:
public void ExecuteDynamicMethod(int number)
{
// Modify these two lines with your app's dll/exe and class type:
Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
Type type = assembly.GetType("YourClassType");
if (type != null)
{
MethodInfo methodInfo = type.GetMethod("function" + number);
if (methodInfo != null)
{
object classInstance = Activator.CreateInstance(type, null);
methodInfo.Invoke(classInstance, null); // null = "no function arguments"
}
}
}
This can then be called for a given value like
ExecuteDynamicMethod(14);
See this SO answer for the inspiration behind this.
Reflection can be used for this purpose. I want to give and keep below example for not only the objective of the question but also for future reference. Also, of course that many function is not good but below code shows the approach that can work with many functions if they have similar name (like starting with "function" keyword).
Assume below is Methods.cs
using System;
using System.Reflection;
namespace YourMethodNamespace
{
public class YourMethodClass
{
public void function1()
{
Console.WriteLine("Function-1");
}
public void function2()
{
Console.WriteLine("Function-2");
}
...
public void function200()
{
Console.WriteLine("Function-200");
}
public static void invokeMethodsDynamically(int randomNumber){
Type yourClassType = typeof(YourMethodClass);
ConstructorInfo yourClassConstructorInfo = yourClassType.GetConstructor(Type.EmptyTypes);
object yourClassObject = yourClassConstructorInfo.Invoke(new object[]{});
//If the constructor has parameters, then we can pass them by this way. Like below;
/*ConstructorInfo yourClassConstructorInfo = yourClassType.GetConstructor(new[]{typeof(int)});
object yourClassObject = yourClassConstructorInfo.Invoke(new object[]{3});
*/
MethodInfo[] methodInfoArr = yourClassType.GetMethods();
foreach(MethodInfo methodInfo in methodInfoArr){
if(methodInfo.Name == "function" + randomNumber){
methodInfo.Invoke(yourClassObject, null);
}
}
}
}
}
Let's say below is Program.cs
using System;
using YourMethodNamespace;
namespace YourProgramNamespace
{
public class YourProgramClass
{
public static void Main()
{
Random random = new Random();
int randomNumber = random.Next(1, 201);
//If Methods.cs is in another Assembly
/*string pathToDllAssembly = #"Domain.dll";
Assembly dllAssembly = Assembly.LoadFrom(pathToDllAssembly);
Type methodsClassType = dllAssembly.GetType("YourMethodNamespace.YourMethodClass");
ConstructorInfo methodClassConstructorInfo = methodsClassType.GetConstructor(Type.EmptyTypes);
object methodsClassObject = methodClassConstructorInfo.Invoke(new object[]{});
MethodInfo methodInfo = methodsClassType.GetMethod("invokeMethodsDynamically");
methodInfo.Invoke(methodsClassObject, new object[]{randomNumber});
*/
YourMethodClass.invokeMethodsDynamically(randomNumber, null);
}
}
}
Also for testing and observing, below link can be used.
https://repl.it/#erdsavasci/ReflectionTest
ok, so in javascript, we can declare an object like this,
var obj={name:"Irshu",age:22};
console.log(obj);
How do we do the same in c#? the reason i ask because my function need to return a string and a bool together. I dont want to create a class for it, and i dont want to use the dictionary. Are there any alternatives?
public void Message(){
var obj=GetObject(val);
Messagebox.Show(Convert.ToString(obj.ind));
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
This is not valid, is it?
.Net supports ExpandoObject since .NET 4.
http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject%28v=vs.110%29.aspx
It lets you declare the object and add properties as your would in javascript.
Traditionally it is for JS interop and I can't recommend it for production work. Tuple<T> is more appropriate as you get strong typing for free. Ultimately you will write less code and see less runtime errors.
What you have in your code is an anonymous type. Anonymous types cannot exist outside the scope in which they are declared. Generally, we use these for transforming LINQ results to temporary objects.
You can't return anonymous types from a method. You can do however something like this:
public void Message(){
var obj = new { ind = "oaiwejf", flag = true };
Messagebox.Show(obj.ind);
}
EDIT
Check this MSDN article
turns out, its posible, one genius on the internet posted this:
public void Message()
{
var obj=GetObject("Irshu");
var y= Cast(obj, new { ind= "", flag= true });
Messagebox.Show(y.ind); //alerts Irshu
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
T Cast<T>(object obj, T type)
{
return (T)obj;
}
private static void AssertNotNullAndAreEqual<T, TK>(T expected, TK actual)
{
Assert.IsNotNull(expected);
Assert.AreEqual(expected, actual);
}
I can call it using:
AssertNotNullAndAreEqual(expected.FirstName, actual.FirstName);
Is there any simple way that I can know the "FirstName" text of the expected object from within this method?
I'd need it for logging purposes and giving proper error messages from within this method.
The C# caller information doesn't help here.
I would rethink that approach, because this might bite back at some point - but if you're really keen on getting some degree of automation, you could try this:
private static void AssertNotNullAndAreEqual<T, TK>(Expression<Func<T>> expected,
Expression<Func<TK>> actual)
{
var memberExpression = expected.Body as MemberExpression;
if (memberExpression != null)
{
var expectedMemberName = memberExpression.Member.Name;
var expectedVal = expected.Compile()();
var actualVal = actual.Compile()();
Assert.IsNotNull(expectedVal);
Assert.AreEqual(expectedVal, actualVal);
//...
}
}
Now your calls would have to look as follows:
AssertNotNullAndAreEqual(() => expected.FirstName, () => actual.FirstName);
Few more caveat
a lot of stuff will not be checked until compile time (luckily type-safety is preserved). It's easy to write calls that will compile correctly, but fail at runtime.
as this is written, it won't work with variables - but if you decide to go this way, it would be pretty easy to write.
Please use at your own discretion :)
If you're using ToString() for another purpose (which I assume you are), you can define an interface and use it as a type constraint on AssertNotNullAndAreEqual(...), or alternately check to see if the objects passed to AssertNotNullAndAreEqual(...) have the interface.
You define an interface, say IDebugString, which has a ToDebugString() method, then you call that to retrieve the info to log.
I'm having trouble with some syntax. I'm not really familiar with interfaces so please excuse my ignorance.
VS2010 is giving me an error at... application.Name = System.AppDomain.CurrentDomain.FriendlyName;
public static void AddApplication(string applicationName = null, string processImageFileName = null)
{
INetFwAuthorizedApplications applications;
INetFwAuthorizedApplication application;
if(applicationName == null)
{
application.Name = System.AppDomain.CurrentDomain.FriendlyName;/*set the name of the application */
}
else
{
application.Name = applicationName;/*set the name of the application */
}
if (processImageFileName == null)
{
application.ProcessImageFileName = System.Reflection.Assembly.GetExecutingAssembly().Location; /* set this property to the location of the executable file of the application*/
}
else
{
application.ProcessImageFileName = processImageFileName; /* set this property to the location of the executable file of the application*/
}
application.Enabled = true; //enable it
/*now add this application to AuthorizedApplications collection */
Type NetFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false);
INetFwMgr mgr = (INetFwMgr)Activator.CreateInstance(NetFwMgrType);
applications = (INetFwAuthorizedApplications)mgr.LocalPolicy.CurrentProfile.AuthorizedApplications;
applications.Add(application);
}
I can make that error go away by setting application to null but that causes a run-time null reference error.
Edit:
Here's where I'm adapting the code from. I hope it gives more context
http://blogs.msdn.com/b/securitytools/archive/2009/08/21/automating-windows-firewall-settings-with-c.aspx
You never initialize
application
before using it here:
application.Name = System.AppDomain.CurrentDomain.FriendlyName;
The variable application is defined as:
INetFwAuthorizedApplication application
You need to assign an instance of a class that implements the interface INetFwAuthorizedApplication.
Somewhere there must be one (or probably more) classes in your project that look something like this:
public class SomeClass : INetFwAuthorizedApplication
{
// ...
}
public class AnotherClass : INetFwAuthorizedApplication
{
// ...
}
You need to determine what class you should use (SomeClass, AnotherClass) then assign an appropriate object, e.g. like this:
INetFwAuthorizedApplication application = new SomeClass();
Interfaces are used to describe what an object does, not what it is specifically. To put into "real world" terms, an interface might be like:
ISmallerThanABreadbox with a FitIntoBreadbox() method. I can't ask you to give me "the smaller than a breadbox" ... as that doesn't make any sense. I can only ask you to give me something that "IS smaller than a breadbox". You have to come up with your own object that makes sense to have the interface on it. An apple is smaller than a breadbox, so if you have a breadbox that only holds items smaller than it, an apple is a good candidate for the ISmallerThanABreadbox interface.
Another example is IGraspable with a Hold() method and FitsInPocket bool property. You can ask to be given something that IS graspable that may or may not fit in your pocket, but you can't ask for "the graspable".
Hope that helps...
I have a three polymorphed classes. Based on user input the class should be set to that user's input. So the child class is decided by a user, and should make for 'class = new inputClass'. The snippet of code looks like:
public void characterGeneration(string classSelected)
{
foreach (string classInList in classes.ClassList)
{
if (classSelected == classInList)
{
PlayerOneStats = new Mage();
}
}
PlayerOneStats.generateStats();
}
Where it says PlayerOneStats = new Mage();, I want the Mage() to be the user input.
I've looked at Activator, Assembly, using Type, trying to cast over to the parent of GenerateStats, but nothing works. I've found many people saying it works, and one link that says it doesn't work. Can somebody please clear this up for me? Thank you very much!
Are you sure Activator doesn't work? Activator.CreateInstace("assembly-name", "type-name") seems like exactly what you want. What doesn't work?
What is the base class of Mage (and the other classes a user can select)? You should be able to do this:
public void characterGeneration(string classSelected)
{
foreach (string classInList in classes.ClassList)
{
if (classSelected == classInList)
{
PlayerOneStats = (GenerateStats)Assembly.GetExecutingAssembly().CreateInstance("YourNamespace." + classSelected);
break;
}
}
PlayerOneStats.generateStats();
}
Make sure that you include the namespace the type you want is contained in and this should work for you:
string classSelected = "testCode.Mage";
var player = Activator.CreateInstance(Type.GetType(classSelected));
Since Activator.CreateInstance() returns an object you will have to cast - in your case it would make sense to cast to an interface that all your player classes implement:
var player = (IPlayerCharacter) Activator.CreateInstance(Type.GetType(classSelected));