What is the basic C# interface scope? - c#

I am having a dispute with another fellow programmer, over the scope of interfaces.
suppose we have the following:
public interface IFoo
{
string Bar { get; set; }
}
public class SomeFoo: IFoo
{
public string Bar { get; set; }
public SomeFoo(string bar)
{
this.Bar = bar;
}
}
public class Consumer
{
public void DoSomething()
{
SomeFoo fooClassInstance = new SomeFoo("test");
IFoo fooInterface = (IFoo)fooClassInstance;
// do something with fooInterface.
}
}
So the question is:
1. Is it possible the fooClassInstance to go out of scope before something else releases the fooInterface instance?
Some argue that the object (fooClassInstance) can go out of scope.
I believe that it cant. Sure, objects may or may not get disposed of by the GC when the GC decides that the object(s) are no longer in scope. However since Interfaces are by design an abstract contract whose members have to be implemented by the object that uses it, than an interface cannot lose its implementation so long as the interface is used. It's not like a whole another object is created of type "interface". The interface is merely a pointer to those abstract members of the implementor.
Can you guys help me resolve this dispute?
Thanks,
<bleepzter />

While there is definitely some confusion in the terms you are using (I'll let someone else tackle that issue), I think I understand what you are saying, and you are basically right.
In particular, it sounds like your coworker believes this is happening:
// Now there is this "SomeFoo" object somewhere in memory.
SomeFoo fooClassInstance = new SomeFoo("test");
// Now there is this "IFoo" object somewhere in memory.
IFoo fooInterface = (IFoo)fooClassInstance;
// Let's say down the road somewhere, fooClassInstance is set to null or a different
// object. Your coworker believes that the object it originally pointed to will then
// have no references to it and will thus be eligible for garbage collection?
If the above is an accurate representation of what your coworker thinks, then your coworker is wrong and you are right. The fooInterface variable contains a reference to the same object that fooClassInstance had a reference to. You can easily verify this simply by doing the following:
SomeFoo fooClassInstance = new SomeFoo("test");
IFoo fooInterface = (IFoo)fooClassInstance;
bool sameObject = ReferenceEquals(fooClassInstance, fooInterface);
If ReferenceEquals returns true, then the two variables are referencing the same object in memory.
If your coworker needs further convincing, try showing him/her something like this:
List<int> list = new List<int> { 1, 2, 3 };
// This cast is actually not needed; I'm just including it so that it mirrors
// your example code.
IList<int> ilist = (IList<int>)list;
// Now we remove an item from the List<int> object referenced by list.
list.Remove(3);
// Is it in ilist? No--they are the same List<int> object.
Console.WriteLine(ilist.Contains(3));
// How about we remove an item using ilist, now?
ilist.Remove(2);
// Is it in list? Nope--same object.
Console.WriteLine(list.Contains(2));
// And here's one last thing to note: the type of a VARIABLE is not the same
// as the type of the OBJECT it references. ilist may be typed as IList<int>,
// but it points to an object that is truly a List<int>.
Console.WriteLine(ilist.GetType());

I think you are muddling the line between instance an reference. fooClassInstance can go out of scope (that is, it can no longer be referenced) even if the instance of the object still exists (because fooInterface still holds a reference to it).
For example, if you do the following, fooClassInstance will not be available after the braces, but fooInterface will.
public void DoSomething()
{
IFoo fooInterface;
{
SomeFoo fooClassInstance = new SomeFoo("test");
fooInterface = (IFoo)fooClassInstance;
}
// do something with fooInterface, but NOT with fooClassInstance
}

Uh, what do you mean by "lose its implementation"? That makes no sense. A type implements an interface, it cannot "unimplement" an interface.
As far as your code example goes, the lifetime of the object allocated ends the instant it no longer has any roots (aka, is no longer reachable by the GC). A reference to it is a reference to it, regardless of the type of the reference (i.e. if the reference type is of some derived or parent type, it doesn't matter).
ISomething Sample() {
Something s1 = new Something();
s2.DoSomething(); // Assuming s is the only reference to s, then it no longer is
// rooted after this expression
Something s2 = new Something();
ISomething is1 = s2;
s2 = null;
is1.DoSomething(); // The reference remains valid and the lifetime of the
// object created continues until we release all
// remaining references to it.
return is1;
}

It sounds like you are correct, but I feel like we're missing part of the discussion since we don't know what you're doing with the object after you create (and cast) it.
In your example:
SomeFoo fooClassInstance = new SomeFoo("test");
At this point, you have one reference to the SomeFoo object referenced by fooClassInstance.
IFoo fooInterface = (IFoo)fooClassInstance;
At this point, you have two references to the SomeFoo object (referenced by both fooClassInstance and fooInterface).
So yes, depending on how you use it, fooClassInstance could go out of scope. But there is still a reference to it (fooInterface) so it wouldn't be garbage collected. Also, the fooInterface reference could be cast back to SomeFoo.

Related

C# Get class declaration name

Is it possible to get the declaration name of a class (dynamically) and pass it as a parameter in the constructor to set the name variable in the class itself?
Example:
public class Foo
{
public string name;
public Foo()
{
name = GetClassName();
}
}
public class SomeOtherClass
{
Foo className = new Foo();
Console.WriteLine(foo.name);
}
As result I would expect it to write: "className".
No. That is not possible. There is no way to pass in a variable name without using a parameter.
This is the closest you can get:
Foo className = new Foo(nameof(className));
That sounds like a weird requirement. A variable is nothing but a reference to an object. The name of that reference has by no means anything to do with what this variable reference. Thus the actual referenced object doesn´t know anything about its references. In fact you may have even multiple references to the same Foo-instance. So how should the instance know to which variable you refer to? So what should happen in the following example:
var f = new Foo();
var b = f;
Now you have two references to the same instance of Foo. The instance can´t know which of hose is the right, unless you provide that information to it by using a parameter (e.g. to your constructor). The thing gets even worse if you have a factory creating your Foo-instance:
void CreateFoo()
{
return new Foo();
}
// ...
var f = CreateFoo();
Now you have a further indirection, the constructor of Foo can surely not bubble though all layers in your call-stack until it reaches some assignement where it may get the actual name. In fact it´s possible that you don´t even assign your instance to anything - although this is merely a good idea:
CreateFoo(); // create an instance and throw it away
Anyway if you want to set a member of an instance to some value, you should provide that value to the instance. The answer by Patrick shows you how to do so.

Returning a private field by ref from a get only property

I have been messing around with structs. I have looked for an example of this but have not found anything.
struct TransformComponent
{
public int X { get; set; }
}
class Foo
{
private TransformComponent _transform;
public ref TransformComponent Transform
{
get { return ref _transform; }
}
}
class Bar
{
Foo testFoo = new Foo;
void TestMethod()
{
testFoo.Transform.X = 5;
}
}
This compiles and works as you would assume it does.
Is there something wrong with doing this that I am not seeing?
The reason why this is interesting to me is that as TransformComponent being a Value Type rather than a Reference Type it would be stored in memory next to the Foo object correct? Rather than possibly somewhere else in memory if it was a Reference Type?
Edit:
After reading the post I realize my question might not have been clear.
Will the _transform be stored next to the Foo object in memory since it is a Value Type and a field of the class?
Edit 2:
Reading the answer, it is clear that the _transform Member is getting allocated along side the Foo instance on the Heap.
If I am not mistaken, I am removing one level of address reference by doing it this way correct?
If I switched TransformComponent to a Reference Type the _transform Member would be a reference to the object allocated in the Heap rather than a reference to the Value itself correct?
Edit 3:
I need to look into how things are allocated more. Thank you to everyone who participated, for your time.
as Transform is part of Class Foo, it get stored on Heap only as it part of userdefined type clas i.e. reference type.
When you mark it as Ref that means you are passing it address not object and what every change made to it will change value stored on the given address.
If you have declared value type in the method then it will get stored on stack, and that adddress will be pass in ref.
So point is when you mark variable as Ref it doesnt allocate memory on heap , it will remain where it is (i.e. on heap/stack). Ref only tells that you are passing address so change made to variable will reflect to adress.
this might help : Reference type modification vs change of reference

C# define that a class instance can never be null (it only contains no data)

Out of curiosity: Is there a way to create a class whose reference to the class instance can never be set to null?
Like haveing only a readonly pointer that can only be set to null by the class itself.
What I have in mind:
I would want to have an easy to read /use object that either exists with data or exists without (shown by an attribute like hasData = false). It is always accessable and should never be null / point to nowhere which as a side effect gets also rid of NullReferenceExceptions for objects that are sometimes supposed to not have a value without the need of checking for null.
This feature does not exists (yet). There is big discussion of non-nullable reference types at Roslyn forum: non-nullable reference types (the one billion $ mistake). But currently you cannot restrict reference type variable from assigning null value.
You can use value type (struct) instead, but it's not stored in heap, passed by value etc.
All other options will not guarantee that someone will not assign null to variable of your reference type. But you still can use something like Null Object pattern to simplify your life (processing objects without data in same way as usual objects).
In such a case, you may want to use a struct instead of a class. Class is a reference type and therefore its default value is null, hence a variable containing an instance can be nulled (assigned null). There is no way to prevent it. On the other hand, struct is a value type and default for struct is an empty struct - i.e. a struct whose members are set to their defaults (0 for an int field, null for a field of a reference type etc.)
Example of a struct
public struct Foo
{
public int Bar;
}
And its usage (notice it is not instantiated but still it is NOT null)
Foo foo;
foo.Bar = 1;
More about structs can be found here on the MSDN sites.
As Anton mentioned, you could use a struct which cannot have a default value of null. But I am thinking you want something more like this:
public class DataObject
{
public static bool HasData
{
get
{
return myObject != null;
}
}
public static DataObject PresistentDataObject
{
get
{
return myObject;
}
}
static DataObject myObject = new DataObject();
}
This code seems like bad practice. And maybe you'd want to resort to something like dependency injection with a singleton which will avoid setting up a state class like this.
Typically, the motivation behind such a question drives the qualities/properties of a solution.
Here, I suppose, the motivation is to avoid runtime exceptions of (faulty) code which tries to access a null reference as if it held an instance.
class Foo<T> {
T data; // might be null or hold an instance...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays(); // might return null...
}
bool DoSomething() {
return data.Value > 5; // might throw an exception...
}
// ... more members...
}
To prevent this type of errors, you could borrow from C#'s cousin language F#.
If the function T GetInstanceOfTInMysteriousWays<T>() by design and contract is permitted to either return an instance or a null value, a better design of that function would be to have it return not T but an Option<T>. Then, the type of Foo.data would not be T but Option<T> and the user code in DoSomething() could not simply access member data.Value. Thus, this common pattern of bugs would be eliminated.
// Improved code from above
class Foo<T> {
Option<T> data; // Option is a struct type and cannot be null...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays();
}
bool DoSomething() {
if (data.IsSome() ) {
return data.TryGetValue().Value > 5;
}
return false;
}
}
Now the only question is, where to find that Option type in C#? There are several github projects creating such a type (google is your friend). You could also consider to link the F# core library and use the Option type defined there, maybe along with a little helper as is shown in this gist snippet.
If your class is named foo, then you would have at least one constructor (possibly more). In that constructor you would assign the variable to false.
public foo(){
hasData = false;
}
As #Anton points out, this only works if the variable is instansiated.
foo f = new foo();
it would still be null if you assigned it as null:
foo f = null;
I'm not sure, I understand the question correctly or not. Let me add
some points here:
Hope that you misunderstand the term Instance, If you create an instance of the class then it will not be null, Let myClass be a class that you have created already. You are not creating any instance of the class by using myClass myClassObject. The myClassObject will became an instance of the class only when an instance of the class is assigned to it, Until then it is null which means not existing.
As others have mentioned, you'd need a struct for that.
However, we can tackle this from a different angle (in a class):
Since the variable can point to null, let's define the variable in a way that it can't be set to null:
private Class1 _c = new Class1();
public Class1 c { get { return _c; } set { if (value != null) _c = value; } }
so c will not be set to null.
A struct per your requirements:
struct Struct1
{
public bool hasData { get { return Data != null; } }
public Class1 Data;
}

The .NET Garbage collector

This is a very basic question. I am debugging some memory leaks and got totally confused. Suppose I have the following:
public class ObjectData : IDataObject
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ObjectRepository<T> where T : IDataObject
{
private Dictionary<int, T> Objects;
public ObjectRepository()
{
Objects = new Dictionary<int, T>();
// load Data
}
public T GetDataObject(int id);
{
return Objects[id];
}
public Reset()
{
Objects = new Dictionary<int, T>();;
}
}
Now suppose I have the following program flow:
public Main()
{
var DataRepository = new ObjectRepository<ObjectData>();
// Constructor called and Data loaded
var myObject = DataRepository.GetDataObject(1);
DataRepository.Reset();
// Call manually the garbage collector or leave it
// Program flow continue after this
}
The question is, will the garbage collector get rid of the collection initially created by the constructor? Or it will not because one of the elements is still referenced in the program flow (myObject)?
It will be collected (eventually), since there is no more references to it. Getting a reference to something in a dictionary doesn't give you any reference to the dictionary itself! Unless that object somehow references the dictionary internally, that is.
To answer such questions ask yourself: Who is referencing the object in question (in this case the overwritten dictionary)?
DataRepository is not. You overwrote the object reference pointing to the old dictionary.
myObject is not because ObjectData does not have any field of type dictionary. It can't reference a dictionary.
Nobody is left to reference the old dictionary.
After your call to Reset, there is no strong references to your initial dictionary. Thus, it will be elected for garbage collection.
Or it will not because one of the elements is still referenced in the program flow (myObject)?
It doesn't matter which objects the dictionary refers to, what matters is who refers to the dictionary. In this case, no one. It's perfectly possible for the dictionary to be collected while its contents are still alive.

Set the instance to null not the variable referencing it

I created an object, and I assigned it to two variables found in separate classes.
If in one class I set the variable to null, it only breaks that reference to the object but the object itself still persists due to the other reference.
How do I set the object to null, so that both references point to null? Without finding every reference.
this is pseudocode. The idea is to lose the reference in both ClassA (ref1) and ClassB (ref2).
public class ClassA
{
public ClassC ref1 = new ClassC ();
static void Main(string[] args)
{
ref1 = null;
}
}
public class ClassB
{
public static ClassC ref2;
public static AssignC (ClassC c)
{
ref2 = c;
}
}
public class ClassC
{
public ClassC ()
{
ClassB.AssignC (this);
}
}
You can't.
You cannot reach into the internals of another class, (well, not conventionally.) This form of Encapsulation makes .Net code much easier to debug.
You could write a function on the class that sets all its members to null, you could do this as an implementation of IDisposable.
When there are no references to an object the Garbage Collector will reclaim the memory, you cannot directly control this.
You could rewrite your example like this.
public class A
{
private C c = new C();
static void Main(string[] args)
{
c.Dispose();
c = null;
}
}
public static class B
{
private static C c;
public static LastC
{
get
{
return c;
}
set
{
c = value;
}
}
}
public class C : IDisposable
{
public C()
{
B.C = this;
}
public void Dispose()
{
if (B.LastC == this)
{
// LastC has not been set by another instance.
B.LastC = null;
}
}
}
You'll note that I've made the static reference accessible via a setter, so that other classes can access it.
Setting null to reference-type variable change only VALUE of that particular variable - reference to object. Good article by Jon Skeet - http://www.yoda.arachsys.com/csharp/parameters.html
In your case its better to wrap object into Singleton pattern. So the setting of null to main variable will destroy the only reference to object and it can be garbage-collected.
It is simply not possible.
References can be either null or point to an actual instance. When you assign, as in ref2 = c; the value of one reference is copied to another reference. After that you have two references to the same instance. (The instance is not copied, for sure, only the reference; these are reference types.)
When you do ref1 = null; that just overwrites the particular reference with one that points to "nothing". It doesn't destroy any instance, just makes a single reference "point" to something else. Other references are unaffected (method parameters with ref or out of currently executing methods could in fact be the same reference, the one which is turned to points elsewhere).
In the question title you say "set the instance to null", but that doesn't really make sense, because an instance is an object (not a reference).
So how to destroy an instance? You can't. The garbage collector might come by at some point (when you are about to allocate a new object) and see that some instances have zero references to them. It will then remove the instances from memory.
You can't "zero" other people's references. Just because you have one references to an instance, there is no way to say "search through the entire application and find other references that happen to point to the same instance right now, and change all those references. That would be a really terrible thing to allow, because people could never be sure when their variables changed out of nowhere.

Categories

Resources