Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have been struggling with a the concept mentioned in the title. I've done a good deal of research and have found some good examples and I have attempted to implement some of them but have reached a road block.
I initially had a class that looked like this:
namespace sysVer
{
public class testSuite
{
/* there is a bunch of test hardware setup
* and acquisition also that is not shown
*/
public struct testResultInfo
{
public testStatus testStat;
public bool warning, error;
public string warnStr, errStr, infoStr, muxDataStr;
public double measDecVal;
public Int16 measIntVal;
};
// NOTE there is no default constructor
public static testResultInfo testCase1()
{
}
public static testResultInfo testCase2()
{
}
public static testResultInfo testCase3()
{
}
// there are about 100 more
}
}
And using a windows form with 105 of checkboxes and a dictionary to determine which function the user wants to run, I was able to call the functions by a string using Invoke Member as follows:
// first attempt
namespace sysVer
{
public partial class SysVerForm : Form
{
public static Pdgu1553ver.testResultInfo tcResult = new Pdgu1553ver.testResultInfo ( )
{
testStat = Pdgu1553ver.testStatus.pass,
warning = true,
error = true,
warnStr = "This is a warning",
errStr = "This is an error",
infoStr = "This is info",
muxDataStr = "Mux data of some sort",
measDecVal = 69.69,
measIntVal = 69
};
// for loop that iterates over checkbox checked items
foreach ( var checkedItem in checkedItems )
{
var funcName = "";
// retrieve function name from dictionary
tcToFuncDic.TryGetValue ( checkedItem.ToString ( ), out funcName );
tcResult = ( testSuite.testResultInfo ) typeof ( testSuite ).InvokeMember
(
funcName,
BindingFlags.InvokeMethod |
BindingFlags.Public |
BindingFlags.Static,
null,
null,
null
);
}
}
}
But I ran into a problem here. When InvokeMember is called the static method is executed and a return type is received but I am not sure if the method is just called or is an actual instance of the class created using the default constructor? I started noticing that private attributes of this class set during one call were not there during another call to a different static function that needed them.
I assumed that I needed an instance of my class so I changed to the following:
namespace sysVer
{
public class testSuite
{
/* there is a bunch of test hardware setup
* and acquisition also that is not shown
*/
public struct testResultInfo
{
public testStatus testStat;
public bool warning, error;
public string warnStr, errStr, infoStr, muxDataStr;
public double measDecVal;
public Int16 measIntVal;
};
// constructor
public testSuite()
{
/* Here I initialize hardware, set variables, and
* run a few other tasks. All of which need to be done
* an exist before this object can be used
*/
}
public testResultInfo testCase1()
{
}
public testResultInfo testCase2()
{
}
public testResultInfo testCase3()
{
}
//... there are about 100 more
}
}
Now, I hit another wall. I needed to do something like this:
testSuite myTest = new testSuite();
var blah = myTest.InvokeMember(
funcName,
BindingFlags.InvokeMethod |
BindingFlags.Public |
BindingFlags.Static,
null,
null,
null
);
But my class does not contain that method. Looking into that I learned that I could change my class to inherit from 'Type' and that I would have to override about 50 or so abstracts from 'Type'. I started down this path but feel that it is likely more work than I need to do here.
I need to have an instance of my class and need to be able to deduce at runtime which non-static method to call. Of the many posts I've read these two: How to invoke a non static method by reflection and invoke non static method in c#
seem to be pushing me in the right direction but I'm still missing something somewhere.
I've already put lots of time in overriding all those functions but am stuck there with how to actually implement the overridden InvokeMember function, I'd hate to undo all that work to try to do something else at this point.
As always, any advice is greatly appreciate. Thank you for your time and consideration.
I get the sense you're convoluting a lot of assumptions and concerns with static, structs, reflection, etc. and losing track of where you want to go. You've apparently tried to solve the wrong problems the wrong way. But I'll address your questions one at a time.
I am not sure if the method is just called or is an actual instance of the class created using the default constructor?
Why would you think that? You didn't post the code of the test methods but I can assure you that InvokeMember actually invokes the member.
I started noticing that private attributes of this class set during one call were not there during another call to a different static function that needed them.
Probably because the test methods create a new testResultInfo each time, but without the code it's impossible to know. But I don't see why that is a problem. What data do you need to "carry over"? Maybe you need a static testResultInfo property on testSuite that you can reuse within the methods?
Looking into that I learned that I could change my class to inherit from 'Type'
I can't see any reason whatsoever why you'd need to do that or what you think that would solve.
Stop trying top band-aid problems that were created by trying to fix other problems, possibly in the wrong way. Back up, analyze your program and think about where different instances are created? should these test methods magically know about the instance that you've created in the form or should they be given that instance somehow? How should you do that? Should you make it an input parameter? Or a static property of the test suite?
Related
My question is: Can I define a static method "meth1" in a static class "classB" that, when called from "classA", searches for a specific field (in "classA", not in the class in which is defined)?
I try to explain better: I need to do something like this:
public class classA
{
string someText;
int anInt;
bool trueOrFalse;
public classA()
{
...
...
var variable = classB.meth1("variableName");
...
...
}
}
public static classB
{
public static object meth1(string name)
{
...
... //use "name" to find the variable with that name in the class from which "meth1" is called.
...
}
}
That because I have to read a backup of "last run values" of variables contained in a .txt file, written line by line as "variable name = value".
So I read the .txt, create an hashtable "backupHashtable" which contains ("variable name";"value"), and then I want to search variables by string "variable name" and reset them to "value".
If someone of you knows a better procedure I'm listening. Maybe the use of a Dictionary?
Thank you!
UPDATING
Ok, now I have a clearer idea of what I want to do: I want to implement a class "ClassB", separate from my main class "classA". In this new class I would have a "meth1" method which, running in a separate thread, saves every 10 seconds (for example) the state of some variables belonging to "classA". To communicate the "meth1" what are the variables that he has to save, I want to use a list containing the names (in the format "string", that's what I thought, but I guess it's not the only way) of these variables.
If you're wondering why I want to do this in a separate thread the answer is this: my application performs some recognition operation of some objects in live stream images from multiple cameras and then ancillary operations must be isolated as much as possible from the main code to increase the speed of execution.
Now, perhaps, it is more understandable what I said before.
Yes, but you also need to pass a reference to the instance of A. Then use reflection to get or set the property.
public static void Meth1(object obj, string propertyName)
{
var prop = obj.GetType().GetProperty(propertyName);
var value = prop.GetValue(obj);
...
}
If I were to get values from a textfile into a class, I think I'd load them in a dictionary first, and then set all properties one by one. (Maybe unless there are, say, hundreds of properties). When using reflection, there is a chance that the textfile contains the name of a property you don't want to be changed from outside.
object value;
if (dict.TryGetValue("someProperty", out value)) { a.SomeProperty = value; }
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am new to programming, could someone please explain me difference between constructor and property in context to C#.
since both used to initialized your class fields, & also which one to choose in a given situation .
Besides all the technical stuff, a good rule of thumb is to use constructor parameters for mandatory things, properties for optional things.
You can ignore properties (hence optional), but you can't ignore constructor parameters (hence mandatory).
For everything else, I'd recommend reading a C# beginners book or tutorial ;-)
A property is just a class member that can be initialized when ever.
Like so:
var myClass = new MyClass();
myClass.PropertyA = "foo";
myClass.PropertyB = "bar";
A constructor is run when the class is created and can do various things. In your "scenario" it would probably be used to initialize members so that the class is in a valid state upon creation.
Like so:
var myClass = new MyClass("foo", "bar");
Constructor is a special type of method from the class to create the object itself. You should use it to initialize everything necessary to make the object work as expected.
From MSND Constructor:
When a class or struct is created, its constructor is called.
Constructors have the same name as the class or struct, and they
usually initialize the data members of the new object.
Properties enable a class to store, setting and expose values needed for the object. You should create to help in the behavior for the class.
From MSND Property:
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily and
still helps promote the safety and flexibility of methods.
Example:
public class Time
{
//
// { get; set; } Using this, the compiler will create automatically
// the body to get and set.
//
public int Hour { get; set; } // Propertie that defines hour
public int Minute { get; set; } // Propertie that defines minute
public int Second { get; set; } // Propertie that defines seconds
//
// Default Constructor from the class Time, Initialize
// each propertie with a default value
// Default constructors doesn't have any parameter
//
public Time()
{
Hour = 0;
Minute = 0;
Second = 0;
}
//
// Parametrized Constructor from the class Time, Initialize
// each propertie with given values
//
public Time(int hour, int Minute, int second)
{
Hour = hour;
Minute = minute;
Second = second;
}
}
Properties should be used to validate the values passed as well, for exemple:
public int Hour
{
//Return the value for hour
get
{
return _hour;
}
set
{
//Prevent the user to set the value less than 0
if(value > 0)
_hour = 0;
else
throw new Exception("Value shoud be greater than 0");
}
private int _hour;
Hopes this help you to understand! For more information about C# take a look at Object-Oriented Programming (C# and Visual Basic).
In C#, I am defining a static field of a specific class. From within the class, I want to be able to display the name of the static field, pretty much like this:
public class Unit {
public string NameOfField { get { return ...; } }
}
public static Unit Hectare = new Unit();
If I now access:
Hectare.NameOfField
I want it to return:
Hectare
I know there is a static function System.Reflection.MethodBase.GetCurrentMethod(), but as far as I can tell there is no way to get the name of the instance containing this current method?
There is also the System.RuntimeFieldHandle structure, but I have not been able to identify any GetCurrentFieldHandle() method.
I am not sure if I am missing something obvious?
Any help on this is very much appreciated.
You should not count on variable names in you developments as they do not exits at runtime.
It's better to initialize Unit with a name directly:
public class Unit {
public Unit(string name)
{
NameOfField = name;
}
public string NameOfField { get; private set;} }
}
public static Unit Hectare = new Unit("Hectare");
Only way around this will be to store that information in the class:
public static Unit Hectare = new Unit("Hectare");
When your code is compiled all variable names are lost and replaced by internal references. There is no way to get that name again.
You can use Reflection to obtain class Fields and properties. Like below:
Suppose you have class with one property:
class Test
{
public static string MySupperField
{
get
{
return "Some symbols here";
}
}
}
......
You can read the property name in such way:
public string[] GetClassStaticNames(Type T)
{
string[] names;
System.Reflection.PropertyInfo[] props = T.GetProperties(); // This will return only properties not fields! For fields obtaining use T.GetFields();
names = new string[props.Count()];
for (int i = 0; i < props.Count(); i++)
{
names[i] = props[i].Name;
}
return names;
}
Hope this will help.
[EDIT]
Returning to your question - No you cant obtain name of current variable.
What you are asking about cant be done because of classes nature, they are objects in memory and reference to one object can be held in many variables, and when you are requesting value of instance field or property it will be actually performed operation with object in memory not with variable wich holds reference to that object. So obtaining name of variable wich holds reference to current instance have no sence
Thanks everyone who has taken the time to answer and discuss my question.
Just to let you know, I have implemented a solution that is sufficient for my needs. The solution is not general, and it has some pitfalls, but I'd thought I share it anyway in case it can be of help to someone else.
This is in principle what the class that is used when defining fields looks like:
public class Unit : IUnit {
public NameOfField { get; set; }
...
}
As you can see, the class implements the IUnit interface, and I have provided a public setter in the NameOfField property.
The static fields are typically defined like this within some containing class:
public static Unit Hectare = new Unit();
My solution is to set the NameOfField property through reflection before the field is used in the implementation.
I do this through a static constructor (that of course needs to be invoked before the Unit fields are accessed.
I use Linq to traverse the executing assembly for the relevant fields, and when I have detected these fields (fields which type implements the IUnit interface), I set the NameOfField property for each of them using the Any extension method:
Assembly.GetExecutingAssembly().GetTypes().
SelectMany(type => type.GetFields(BindingFlags.Public | BindingFlags.Static)).
Where(fieldInfo => fieldInfo.FieldType.GetInterfaces().Contains(typeof(IUnit))).
Any(fieldInfo =>
{
((IUnit)fieldInfo.GetValue(null)).NameOfField= fieldInfo.Name;
return false;
});
There are some shortcomings with this approach:
The static constructor has to be invoked through manual intervention before any Unit fields can be accessed
The NameOfField setter is public. In my case this is no problem, but it might be when applied in other scenarios. (I assume that the setter could be made private and invoked through further reflection, but I have not taken the time to explore that path further.)
... ?
Either way, maybe this solution can be of help to someone else than me.
I've never really questioned this before until now. I've got an input model with a number of fields, I wanted to present the string names of the properties through the input model so that my Grid can use them:
public class SomeGridRow
{
public string Code { get;set; }
public string Description { get;set; }
public const string Code = "Code";
}
Obviously, this gives the error:
The type 'SomeGridRow' already
contains a definition for 'Code'
Why can the CLR not cope with two properties of the same name which are, in my eyes, separate?
string code = gridRow.Code; // Actual member from instantiated class
string codeField = SomeGridRow.Code; // Static/Const
I'm now just using a child class called Fields within my inputs now, so I can use SomeGridRow.Fields.Code. It's a bit messy, but it works.
Because you can also access static (or, non-instance in this case) properties in the same way (inside the same class), and it would be a bit confusing, for example:
public class SomeGridRow
{
public string Code { get;set; }
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
Because both this:
public class SomeGridRow
{
public string Code { get;set; }
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
And this:
public class SomeGridRow
{
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
are valid ways to access properties, static or not. It doesn't answer the "why can't I?" question, but more of the why it's not allowed...it would be far too ambiguous IMO.
It probably could, but the designers of C# wanted to avoid ambiguities that can come from such use (abuse?) of language features.
Such code would end up being confusing and ambiguous to users (did I want the instance or the static method call?, Which one is right?).
In addition to the points already made about ambiguity, i would say that the naming needs to be relooked in such a case.
If two variables / fields having the exact same name in the same context i.e class but different values to me sounds more like a naming issue.
If they are exactly same, you dont need 2 fields.
If they are slightly different, you should have more accurate names.
In some other languages with a similar syntax, one can access a static member through an instance. So you could access both string.Empty and "abc".Empty.
C# doesn't allow this (though it does sort of from inside the class or a derived class, in that you can omit the class name for a static member and can omit this for an instance member), primarily to avoid confusion (I find it more handy than confusion tbh, but that's just me, I like switch fall-through too so what do I know).
Having introduced a stricter rule to allow for less ambiguity, it would be counterproductive to allow a new looser rule on the back of it that allowed for more. Think how many "why must I use this with property X but not property Y?" questions SO would have if it was allowed (we'd have to force this with property X to be clear we meant the instance member).
I am looking on how to get the object (or object type) that another object is created in. For example:
public class RootClass
{
public class A
{
public void MethodFromA()
{
}
}
public class B
{
public A A_object = new A();
public void MethodFromB() { }
}
B BObject = new B();
A rootAObject = new A();
public void DoMethod(A anA_object)
{
}
main()
{
/* Somehow through reflection
* get the instance of BObject
* of type B from only the info
* given in anA_object or at
* the very least just know that
* anA_object was created in
* class B and not root. */
DoMethod(BObject.A_object);
/* Same as above except know that
* this A object came from root
* and is not from B class */
DoMethod(rootAObject);
}
}
Additional Information:
This was just a quick code to simulate part of a large project I have. The problem is I have a custom class that is instantiated many many places in various other classes. This custom class has a function that should be able to call any function in it or any function in the class that instantiated it. Very generic processing, but needed. Basically I need the inverse of ".". So with objectA.objectB, I need to find objectA only from passing in objectB to some function.
Thanks!
No - this information isn't stored anywhere. Note that even if it were, it could easily become out of date, effectively. For example:
// Code as before
BObject.A_object = rootAObject;
rootAObject = null;
DoMethod(BObject.A_object);
What should that now show? The current value of BObject.A_object was created as rootAObject, but the current value of rootAObject is null. If you'd want that to show BObject as the "owner" then you're not really talking about creation at all... and at that point, you need to deal with the possibility that an object has multiple references to it.
Please give us more information about the bigger picture: what problem are you really trying to solve?
I believe what you're looking for is the property DeclaringType, defined on the System.Type instance that you're interested in. See DeclaringType documentation.
DeclaringType will only tell you the enclosing type of the code model, but what you are after is identifying object creation point.
There is no easy way to do it other than reading the individual MethodBody IL. IL code for creating an object is newobj. To implement this, you will need to read the MethodBody for every method in your assembly and identify the method that contains newobj instruction with type operand of the object type you are after.
Solved by making all my objects derive from a custom object with a parent parameter.