Since I am building a physics teaching platform, I need to know the total force that is acting on an object at the moment. This way, I may draw arrows showing this resultant force for students to understand what is going on.
I dug into the source of Farseer and found the internal Vector2 variable Force. Since it is internal, I cannot access it from my teaching platform since they are in different assemblies.
Will anything bad happen if I change the modifier to, let's say private, and add a getter function to it?
OR
Is there a better way to get the resultant force currently acting on an object?
Since it seems you have access to the source, the easiest approach to expose that variable is to add a public getter to the class in which it resides. An instance of that class will have access to the internal variable.
EDIT: (Added code examples)
It is all about where the code accessing the internal value exists. Hopefully the example below will illustrate this for you. Assume that you have a solution with two projects, one called ExternalAssembly, the other MyApplication. MyApplication has a reference to ExternalAssembly to access its classes.
Project: ExternalAssembly
namespace ExternalAssembly
{
public class MyClass
{
internal string hiddenString;
public MyClass()
{
this.hiddenString = "This is my value.";
}
public string Exposed
{
get { return this.hiddenString; }
}
}
public class MyClass2
{
private MyClass classInstance;
public MyClass2()
{
this.classInstance = new MyClass();
}
public string Exposed2
{
get { return this.classInstance.hiddenString; }
}
}
}
Project: MyApplication
namespace MyApplication
{
using ExternalAssembly;
public class CallInternalTest()
{
MyClass classInstance = new MyClass();
MyClass2 class2Instance = new MyClass2();
// this will fail since hiddenString is an internal variable
Console.WriteLine(classInstance.hiddenString);
// this will succeed since Exposed is a public member
Console.WriteLine(classInstance.Exposed);
// this will also succeed since Exposed2 is a public member
Console.WriteLine(class2Instance.Exposed2);
}
}
Related
Right now in my code, I have an abstract class, which contains a nested class. In the constructor of every class implementing my abstract class, I will have to construct an instance of the nested class, and pass a reference to the current object to the nested class, as demonstrated below.
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo()
{
this.SpecialStuff = new SpecializedClass(this, "stuff"); // <= This is the issue
// More stuff
}
}
As you can see, whenever I need to call new SpecializedClass(), I have to pass a reference to this. Is there a way to do this automatically, so the classes inheriting from MainClass don't need to keep passing references down?
There answer is basically no. The stack frame does not contain a reference to the calling object (if any), there is no way to get at it fundamentally unless you pass it in, or want to walk the stack (bad idea).
There are however situations where you can use expression trees for more complicated less trivial problems. however, they hardly apply here, and would be more printable characters anyway.
I guess another approach would be an extension methods, however you are just kicking the this ball up the road and creating more code for no good reason
Which leaves with a instance method or base class...
Lastly, although common, I would double check you actually need the calling object. This can easily brush up on design issues such as the Single Responsibility principle (SRP) and Separation of concerns (SOC) among others
All things being equal, if you need it then just pass it in.
No, this is not possible.
Think about it: You could run SpecialStuff = new SpecializedClass(this, "stuff"); in a static function. Then what would the value of this be?
It seems that you could push that functionality into the base abstract class.
Now you only need to call the SpecializedClass and pass this once
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
public MainClass(object stuff)
{
this.SpecialStuff = new SpecializedClass(this, stuff);
}
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo() : base("stuff")
{
// More stuff
}
}
I have a class Computer.cs, which belongs to the form Computer, and I have an independent class Indicators.
In my code I'm getting an error:
Incompatibility accessibility: accessibility return type "WF.Code.Indicators"
method is below than accessibility return type "WF.Computer.ShowForm ()"
What is that means?
Computer.cs
namespace WF
{
public partial class Computer : Form
{
Code.Indicators indicators = new Code.Indicators();
public Computer()
{
if (indicators.isComputerAlreadyRunning == false)
{
InitializeComponent();
indicators.isComputerAlreadyRunning = true;
}
}
public Code.Indicators ShowForm() // Error
{
return new Code.Indicators(indicators.isComputerAlreadyRunning);
}
}
}
Indicators.cs
namespace WF.Code
{
class Indicators
{
public Indicators(bool isComputerAlreadyRunning)
{
this.isComputerAlreadyRunning = isComputerAlreadyRunning;
}
public bool isComputerAlreadyRunning = false;
}
}
Your method:
public Code.Indicators ShowForm() // Error
{
return new Code.Indicators(indicators.isComputerAlreadyRunning);
}
It returns an Indicators object and is of public visibility. However the type Indicators itself is not public, it's internal (by default, since you did not specify it ; see this answer for more information).
Declare the class Indicators as public to solve the issue, or set the method ShowForm as internal.
Edit:
To better explain why the compiler complains, imagine your code is actually compiled to a library. Somebody includes this library from another assembly to use it, and this somebody is going to call this public method ShowForm(because he can!).
He is going to get a reference pointing to an Indicators but from his point of view (actually from his assembly's point of view), he does not know what the class Indicators is, because its visibility is internal (as I said, by default). internal elements are not exposed to other assemblies on the contrary of public elements. This creates an incoherence and that it the reason why the compiler complains.
It means that since ShowForm is public the return type must also be public.
you Indicators class is now :
namespace WF.Code
{
class Indicators
{
public Indicators(bool isComputerAlreadyRunning)
{
this.isComputerAlreadyRunning = isComputerAlreadyRunning;
}
public bool isComputerAlreadyRunning = false;
}
}
but should be :
namespace WF.Code
{
public class Indicators
{
public Indicators(bool isComputerAlreadyRunning)
{
this.isComputerAlreadyRunning = isComputerAlreadyRunning;
}
public bool isComputerAlreadyRunning = false;
}
}
in .NET if you instantiate a class outside the class' area then either should be internal or public code access.. otherwise such like you created class as private ( if there is no code access implementation as your implementation of Indicators - class Indicators- compiler accept that as private and you can't access out of the class)
Even if it was internal code access and you refer it as public you will get the same exception..
when your class' code access is public then should be all instances / inside methods or calls should be public, if it is internal then can be internal or private or protected
In the C# code listed below, I get a "NullReferenceException" with the error:
"Object reference not set to an instance of an object"
I guess the error is related to the inheritance and/or the template definitions. The list gets initialized, and when debugging I can confirm that the list does not point to NULL. I can't figure out how to do this in another way. (Sorry about the confusing class names / structure). The exception happens here: this.localSMT.doSomething(base.list);
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
}
}
public class VTEST_FSUB<V> : VTEST<V>
{
public VTEST_FSUB()
{
do_virtual();
}
public void do_virtual()
{
this.localSMT.doSomething(base.list);
}
}
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB();
}
}
public class LocalSMT<V>
{
public LocalSMT() { }
public virtual void doSomething(List<V> value) { }
}
public class VTEST_SUB : LocalSMT<int>
{
public VTEST_SUB(){}
public override void doSomething(List<int> value) {
System.Console.WriteLine("VTEST_SUB VIRTUAL");
}
}
class Program
{
Program() {}
static void Main(string[] args)
{
VTEST_RUN run = new VTEST_RUN();
}
}
The problem is that the VTEST_FSUB<V> constructor body is executing before the VTEST_RUN constructor body. So when do_virtual is called, localSMT is still null. Then do_virtual tries to call a method on localSMT, hence the exception.
Basically the initialization order for any class in the hierarchy is:
Initialize variables which have been declared within an initializer at the point of declaration (any other variables just have the variable type's default value)
Chain up to the base class initialization
Execute the constructor body
See my article on constructor chaining for more details.
Lessons to learn:
Avoid public fields. If you use private fields, it's easy to find every piece of code that reads them and writes to them
Ideally, use readonly fields: if you'd passed the value up the constructor chain and set it in the VTEST<V> constructor, you wouldn't have had a problem. (Admittedly readonly fields can still be a pain because of the next point...)
Avoid virtual method calls in constructors. In this case that wasn't the problem, but you could easily have had the same issue if do_virtual had been abstract in VTEST_FSUB<V> and overridden to call localSMT.doSomething in VTEST_RUN. It would still have executed before the constructor body had run, which would be surprising. Anything you call within a constructor is operating on a partially-initialized object, which is a precarious situation.
Avoid large inheritance hierarchies. They're a pain to work with and reason about.
Follow .NET naming conventions! Your code is partly hard to read because it's so unidiomatic. Even when you're just giving sample code, at least follow the capitalization conventions.
try:
public void do_virtual()
{
localSMT=new LocalSMT<V>();
localSMT.doSomething(list);
}
in public class VTEST_FSUB<V> : VTEST<V>
You are not instatianing localSMT before using, so it's not working.
EDIT: OR
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
localSMT = new LocalSMT<V>();
}
}
initialize it in constructor, preferable.
Second solution is cleaner.
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB(); // BAD! localSMT isn't initialized yet!
}
}
I believe that you have failed to new up one of your objects:
public void do_virtual()
{
localSMT = new LocalSMT<V>();
localSMT.doSomething(list);
}
Make sure that when you are trying to use an object that you initialize them! And don't worry too much, this is a very common problem in coding.
I have created an engine that takes in 3rd party plugins (DLL's) that implement an interface.
Since I have no control over the code that gets plugged in, I want to be able to run 1 specific method (from the interface) from the correct class (GetTypes loop untill I find the interfaced class ).
Since anyone can create nice constructor code that executes on Activator.CreateInstance, I can solve that by using FormatterServices.GetUninitializedObject. But that does not help when code is being initialized on fields in the class.
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
//I only want this run.
public string MyProperty{
get {
return "ANiceConstString";
}
}
}
The problem with both ways (CreateInstance/GetUninitializedObject) is that the constructor of someotherclass will be run.
Before you start analyze my needs. This is only run in the initializing of the engine to get a set of standard values. If this get'er relies on other initialized values the "plugin" will be marked as failed as there is no valid value returned. If not marked as failed, later on the class will be loaded properly with Activator.CreateInstance().
So stick to this question:
Does .Net support any way to create an 100% non-initialized class?
Update for the answers. I tested this before I posted my question.
For the answer that someotherclass wont run, I allready tested that and it is run if static.
public class myclass : myinterface {
static Tutle test;
public myclass () {
test = new Tutle();
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject does not.
public class myclass : myinterface {
static Tutle test = new Tutle();
public myclass () {
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject shows the messagebox.
Is there a way to get around static field intializers and ctors?
Simply:
var obj = (myclass)FormatterServices.GetUninitializedObject(typeof(myclass));
That will not run the constructor / field initializers. At all. It will not run the constructor for someotherclass; name will be null.
It will, however, execute any static constructor that exists, if necessary under standard .NET rules.
HOWEVER! I should note that this method is not intended for ad-hoc usage; its primary intent is for use in serializers and remoting engines. There is a very good chance that the types will not work correctly if created in this way, if you have not subsequently taken steps to put them back into a valid state (which any serializer / remoting engine would be sure to do).
As an alternative design consideration:
[SomeFeature("ANiceConstString")]
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
}
Now you can access the feature without instantiation; just use:
var attrib = (SomeFeatureAttribute)Attribute.GetCustomAttribute(
type, typeof(SomeFeatureAttribute));
string whatever = attrib == null ? null : attrib.Name;
with:
[AttributeUsage(
AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
public sealed class SomeFeatureAttribute : Attribute
{
private readonly string name;
public string Name { get { return name; } }
public SomeFeatureAttribute(string name) { this.name = name; }
}
I'm trying to create a class (in C#) that serves as an environment for my application.
I'm trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is, that I want to be able to change the properties of this environment class (public setters), but at the same time I want the classes that receive the environment to be unable to use these setters.
I can't seem to find a good way to phrase my question (which I figure is a part of the reason I can't find anything like this on Google or msdn), but to put shortly, I want to create a class with setters that are public only for some of my objects and not for all.
I'm currently amusing the following idea:
Avoiding the public setters all together, and expose the private fields using event registration.
The class will register to events in a new third object (sent as a parameter to the constructor). The methods that will be registered by the environment are not much more then setters, and so triggering these events will "allow access" to the private fields.
I'd love some ideas (seeing as I feel that mine isn't all that great), or better yet some patterns I could make use of.
Thanks in advance
Isn't "internal" sufficient for what you need?
And you could move the setters into an interface as explicit implementation. Then they are hidden from the public interface and only accessible if you cast to the interface.
And if you want to make really sure that nobody else can call it you can add some parameter to these functions where you expect a certain token object which you only give to trusted classes.
void SetX(int value, object token)
{
if(token!=correctToken)
throw new ArgumentException("wrong token");
x=value;
}
You could create a proxy, and send that proxy to your entity classes.
class MyClass
{
public int MyProperty { get; set; }
}
class MyProxyClass
{
public MyProxyClass(MyClass myClass)
{
_myClass = myClass;
}
private MyClass _myClass;
public int MyProperty
{
get { return _myClass.MyProperty; }
}
}
You could try using Friend assemblies. That will allow only the assemblies you specify to have access to your privates (snicker).
Maybe i understood something not quite well, but i think Jon had a quite similar problem which he described here. Maybe this can help you.
How about
class Callee
{
public void SetX(TypeOfCaller caller, int value)
{
}
}
class TypeOfCaller
{
public void Do()
{
Callee instance;
//..
instance.SetX(this, 5);
}
}
Doing so; you can also use Visual Studio' Find References feature! In case you want multiple types of caller; you can either opt for class hierarchy or can simply have required overloads
Why not return clones of your protected objects instead of the actual objects? Solves the problem without adding any more complexity.
public class MyService
{
private List<MyObject> _protectedObjects = new List<MyObject>();
public MyObject GetItem(int id)
{
return (MyObject)_protectedObjects.First(i => i.Id == id).Clone();
}
}
public class MyObject : ICloneable
{
//[...]
public object Clone()
{
return MemberwiseClone();
}
}