Brief understanding of interfaces - c#

I have an interface which says setMaster();
and 2 classes from which i`m setting the respective master pages based on the scenario.
I need to understand what the following code means:
Control pageControl = LoadControl(pageControlPath);
if (pageControl is IVariableMasterPageControl)
{
((IVariableMasterPageControl)pageControl).setMaster();
}
My Code:
Interface:
interface IVariableMasterPageControl
{
void setMaster();
}
Classes:
public class VariableMasterControl1 : System.Web.UI.UserControl, IVariableMasterPageControl
{
public void setMaster()
{
this.Page.MasterPageFile = ("~/ui/" + SiteConfiguration.UIID + "/MasterPageOne.Master");
}
}

The code you are showing loads a UserControl dynamically. The call to LoadControl method returns an instance of type Control. This can be any control that might or might not implement the interface IVariableMasterPageControl. So, if you want to call the setMaster method, you need to check whether the control implements the interface before accessing the control over the interface. This is what the if statement is doing.
The is Statement checks whether an object is compatible with a given type so that it can be cast to that type. In your case, the line
if (pageControl is IVariableMasterPageControl)
checks whether pageControl implements IVariableMasterPageControl so that it can cast it safely in the next line.
As you need the reference to the interface afterwards, an alternative would be to use the as operator:
Control pageControl = LoadControl(pageControlPath);
var varMasterPageCtrl = pageControl as IVariableMasterPageControl;
if (varMasterPageCtrl != null)
varMasterPageCtrl.setMaster();

It seems to me that you are doing custom ASCX controls, some of which implement the interface IVariableMasterPageControl. The code which you have trouble understanding is checking, if the control in question implements the interface or not. If it does, it accesses the method setMaster() of the control - which obviously had to be implemented.
The code
if (pageControl is IVariableMasterPageControl)
Is the part where the check is done to see if the control actually implements the interface or not. This can also be done in the following manner;
if (pageControl.GetType() == typeof(IVariableMasterPageControl))
Take a look at this link: How to compare types. May help you out comparing types and understanding more in depth the concept.

in this case, the is keyword basically says: "if this instance of PageControl implements the interface IVariableMasterPageControl, then call the interface's SetMaster() method for that PageControl."
The check using the is keyword makes sure, that your object actually has a method SetMaster() to call. You could iterate through a bunch of PageControl objects, but there's no guarantee that all of them would implement the interface. Calling a non-existent method without a check would certainly either cause an Exception or could even call the wrong code (if, say, one of the PageControl objects implements an other interface that just happens to also define a method SetMaster()).

Related

What's the sense of some interfaces and of interfaces in general?

I was looking at some interface implementations as I couldn't use the 'using' keyword to be sure to dispose properly a FileInfo object in C#, but compiler gave me this error:
'System.IO.FileInfo': type used in a using statement must be implicitly convertible to 'System.IDisposable'
So, I start documenting about implementations of these particular interfaces.
I ended up seeing that all reduces to typing :IDisposable next to the class name and add a Dispose() method myself, and that's how you make an IDisposable.
First question:
What's the sense of this? Shouldn't the framework creators make those items -disposable/nullable/whatever common use interface you want- without having us to worry about it?
It's 2 years that I work as a programmer but many years that I do as a hobby and I never understood why interface are useful or what is the purpose of them. They actually seem pretty useless to me.
From what I understood their only purpose is to serve as a "contract", which is a definition I never fully understood. People like nto say contrat while they could say "It simply means that you must reimplement all the methods of the class you inherit from, even if you make them empty", instead of that awkward "contract" definition.
Anyway, why is that? Why do I need compiler to tell me that I need to implement those methods? I guess I'll never get that.
Usually I grasped concept from studying or apllying them while coding, but I swear I never found or seen for me nor my coworkers, a situation where an interface was useful, needed, a good choiche or something convenient...
I guess I'll end up never using them even if I see people do use them a lot... Why?
C#, as with many other languages, doesn't support multiple inheritance. See the Diamond Problem for example.
In any case, interfaces are C#'s way to approach multiple inheritance by avoiding some of the problems that go with it. If Class A had a method called Foo() and Class B also had a method called Foo() how could you possibly resolve which one to call when you derive from both? Interfaces by specifying what and object can do, but not how it does it.
Consider IList<T> -- the generic form of a collection that represents an expansible list. It has methods such as Add, Remove, and Clear. If someone uses your class, they shouldn't need to worry about your implementation details, only that it works. Thus, under the hood you can have a List<int> or a LinkedList<int> and it will still function the same to your clients, because you exposed only the interace -- the base contract -- for them to use.
You will use interfaces, undoubtedly. In fact, if you were writing a using statement then you were already using one.
The point of a using statement is to create an object and ensure that it is exposed at the end of the block. In order to be able to dispose the object, it must have a Dispose method. That's where the IDisposable interface comes in.
The IDisposable interface defines the Dispose method. Any class that implements IDisposable signs a contract to implement that Dispose method. The using statement requires that an object have a Dispose method in order to be able to dispose it at the end of the block and the way that it knows that that method exists is the fact that the object you're using implements IDisposable.
This sort of thing is seen all over. When you write a foreach loop, the object that you loop over must implement IEnumerable. Under the hood, the foreach loop uses the functionality defined by that interface to enumerate the specified list.
Similarly, in order to bind a WinForms control like a ComboBox, ListBox or DataGridView to a list of data, that list must implement the IList interface because the underlying data-binding mechanism uses the functionality defined by that interface.
That's basically what interfaces do: they guarantee that a specific set of functionality will be available. They make no promises about how that functionality will be implemented or what other functionality may or may not also be provided.
Think about how interfaces work elsewhere. You use a computer so you are presumably familiar in a general sense with the USB interface. In order to be USB compliant, a device must provide a specific set of functionality. How it does that and what else it does is irrelevant to the USB port on the computer though. As long as it has an appropriate USB plug that can successfully send and receive the appropriate messages then it will work.
Think of your using statement as an IDisposable port. It doesn't matter what your object does when it's Dispose method is called or what other properties and methods it has, as long as it has a method named "Dispose" that has no parameters and doesn;t return anything, it can implement IDisosable and be accepted by the using statement.
Concerning IDisposable in particular: First of all, being disposable is something very different from being nullable.
Variables of every reference type are automatically nullable, which means that you can set them to null. You do not need to implement IDisposable for that.
When you implement the IDisposable interface, you do so to free resources that the runtime cannot automatically free, or that should simply not be subject to (somewhat non-deterministic) garbage collection.For example, you might write a class whose instances open a file and write to it - when an instance of your class is not needed any more, the file should be closed. It should be closed then and there (because something else may want to access the file as of that moment), not "at some point after the class is not needed any more, at the latest when the process is terminated". Therefore, you should declare your own class to implement IDisposable (so users of your class know Dispose needs to be called, and also so they can use your class in a using block) and implement the Dispose method in a way that closes the file.
Now, as you said, interfaces in general serve as a "contract" - a guarantee for callers that your class implements a specific set of members. Thus, the simple answer to your question
Why do I need compiler to tell me that I need to implement those methods?
is "So they can be called."
Consider the following example - first, an interface, and two classes implementing it, are declared:
public interface ISomeInterface
{
bool DoSomething();
int SomeValue { get; }
}
public class Example1 : ISomeInterface
{
public bool DoSomething()
{
return true;
}
public int SomeValue {
get {
return 42;
}
}
}
public class Example2 : ISomeInterface
{
public bool DoSomething()
{
return DateTime.IsLeapYear(DateTime.Now.Year);
}
public int SomeValue {
get {
return DateTime.Now.Year;
}
}
}
Now, let's add a class with a method that returns an implementation of ISomeInterface:
public class SomeMasterClass
{
public static ISomeInterface CreateObject()
{
if (DateTime.Now.Year % 3 == 0) {
return new Example1();
} else {
return new Example2();
}
}
}
Depending on internal conditions, either an instance of Example1 or an instance of Example2 is returned. When invoking the method, you do not know which class will actually be instantiated, and you do not need to know - because both implement the interface whose members you are going to use:
ISomeInterface myObject = SomeMasterClass.CreateObject();
Console.WriteLine(myObject.DoSomething());
Console.WriteLine(myObject.SomeValue);
Without the interface, the return value of SomeMasterClass.CreateObject() would have to be typed as System.Object (because that is the most specialized common ancestor of Example1 and Example2. However, as both classes implement the ISomeInterface interface, and thus fulfil the contract imposed by that interface, you can rely on their providing of implementations for the DoSomething method and the SomeValue property.

Casting an interface to another interface that it does not inherit

I'm hoping someone here can explain what incorrect assumptions I'm making. In C# 4.0, I have 2 interfaces and a class that implements them both. In a method I declare a variable with the type of the first interface, instantiate it using the class that implements both interfaces and can somehow cast it successfully to the second interface like in the following code:
public interface IFirstInterface
{
void Method1();
}
public interface ISecondInterface
{
void Method2();
}
public class InterfaceImplementation : IFirstInterface, ISecondInterface
{
public void Method1() { }
public void Method2() { }
}
public class SomeClass
{
public void SomeMethod()
{
IFirstInterface first = new InterfaceImplementation();
first.Method1();
// Shouldn't the next line return null?
ISecondInterface second = first as ISecondInterface;
// second is not null and the call to Method2() works fine
second.Method2();
}
}
I'm trying to understand why the casting is successful. Yes, the class implements both interfaces, but I would think that since the first variable is declared as IFirstInterface (which doesn't inherit from ISecondInterface), the casting should still fail.
I've also tried restructuring my code in other ways, such as not using 'as', but the cast is still successful.
What am I missing?
From your example, you should be good by testing type type before calling any of the functionality. The first creation will create a fully qualified "InterfaceImplementation" that supports both interfaces. However, you are putting it into a declared type of only the first interface. So from the "first" object's perspective, it only cares about anything associated as an IFirstInterface implementation.
Now, on to you second... Even though you've created the object, you can still ask... By the way... are you also a Second Interface? If so, do this...
IFirstInterface first = new InterfaceImplementation();
if( first is ISecondInterface )
// typecast since the second interface is legit, then call it's method 2
((ISecondInterface)first).Method2();
The actual type of the instance first points to implements both interface. So obviously both Method1 and Method2 are available on the object.
The static type of first only lets you access Method1. The static type of second only lets you access Method2. I you declare a reference to the object using either of the interfaces, you just select to view the instance as an object fulfilling the selected contract (the interface).
As InterfaceImplementation implements both interfaces, you have the option of referring to the instance using either of the interfaces.
If you look from the concrete object's point of view, you can say "I'm a IFirstInterface, but I'm also a ISecondInterface". Is that what you mean? The question you described, would end up in casting just inside a inheritance/implementation chain.
The only thing you're missing is that that's exactly how it's meant to be, and that's a useful feature, not a problem. When casting, you can think of the code as basically saying, "I don't care what I knew this object's type was, I want to see if it can be converted to type T". In this case, since the underlying object is of type InterfaceImplementation, regardless of the fact that it's currently known as an IFirstInterface, the answer is that yes, it can be converted to an ISecondInterface.
Welcome to polymorphism. The object first is always going to be an instance of InterfaceImplementation. How you choose to reference it doesn't affect what the object truly "is." This is how the concept of abstraction works as a whole.
This really indicates a design flaw. The client sort of knows that both interfaces are implemented by the same object. For you example that's fine but if those interfaces were implemented separately, you wouldn't be able to jump form the first to the second one. Ideally it would be better to have some kind of query interface where you could go from one type to the other.

Is there a way to hide/show certain methods when instantiating an object?

This question came to mind while I was writing a class that iterates over a list, with methods next() and previous() that will continuously loop (e.g. if at the last object, return it, and then reset index to 0)
In the constructor I was pondering adding a boolean variable, which if true would just act like a regular iterator with only next() methods and no looping. In this case, having the method previous() would make no sense. So I'm curious, is it possible to hide the previous() method in this case. Is it possible to achieve this somehow in Java or C#?.
What about other languages?
C#
It is possible by making the two methods part of two different interfaces, and casting the object to one of the two interfaces. For example:
interface ILoopingIterator
{
void Next();
void Previous();
}
interface INonLoopingIterator
{
void Next();
}
class PlaysItBothWays : ILoopingIterator, INonLoopingIterator
{
void ILoopingIterator.Next()
{
this.NextCore();
}
void ILoopingIterator.Previous()
{
// since this code will never be shared anyway, put it here
}
void INonLoopingIterator.Next()
{
this.NextCore();
}
private void NextCore()
{
// do stuff here; this method only exists so that code can be shared
}
}
Note that I have made the class implement both interfaces explicitly; this way, users of instances are forced to select which "mode" they want to use the class in. You could implement only one interface explicitly instead (providing a "default" mode that can be changed).
and now:
var looping = (ILoopingIterator) new PlaysItBothWays(); // selects mode A
var nonLooping = (INonLoopingIterator) new PlaysItBothWays(); // selects mode B
Of course this does not stop anyone from casting the instance to the "other" interface if they want to, but if the programmer wants to subvert their own code they can also use reflection which allows much more than that.
Java
In Java, the above is not possible. You can come close by having the class expose methods that return instances of one of the two interfaces, and using the returned value. Of course then the object is really a factory and not a service provider, so that's feels like cheating on the problem.
class PlaysItBothWays
{
public ILoopingIterator asLooping() { return /* something */ }
public INonLoopingIterator asNonLooping() { return /* something else */ }
}
Rather than passing a boolean to a constructor, you should simply use inheritance.
Suppose you have a base iterator that supports only next(). If that's the only functionality you need, instantiate it.
To provide more functionality, inherit from this base iterator, make a class called TwoWayIterator or something like that, and provide a previous() method.
Both of these classes will share a common super class, so you can treat them as one, and you can hide the previous() method by treating an instance as its base class.
It is not possible to hide a method like that in a statically typed language. The best you can do is implement the method to throw an exception (or equivalent) if the method is called.
There are tricks that you can do to make it appear like the methods are not there. For instance, having the class implement two interfaces, and using different factory methods to create them. However, they don't work if the constructor is used directly, or if you want the choice to be determined by the value of a constructor or factory method parameter.
Not in Java. You can't "Hide" methods at runtime. I'd suggest you to create Two interfaces
, one with the next method and the other one extending the first one and adding the "previous" method. Then, you can have 2 factories methods to create an instance of one of these classes.
Please take a look to the Java "Iterator" class
interface Iterator<T> {
T next();
}
interface LoopingIterator<T> extends Iterator<T>{
T previous();
}
Then you can cast them. Similar to the previous C# answer
You can't hide class members at run time (well, not in C# anyway - not sure about Java). If you so worried about Previous() method being used in the context where it is not doing anything useful, then simply have it throw InvalidOperationException in that case.
It is also worth noting that .NET already has standard "iterator" interface. It is called IEnumerable (and generic version IEnumerable<T>) and is forward-only.

Force calling the derived class implementation within a generic function in C#?

Ok so I'm currently working with a set of classes that I don't have control over in some pretty generic functions using these objects. Instead of writing literally tens of functions that essentially do the same thing for each class I decided to use a generic function instead.
Now the classes I'm dealing with are a little weird in that the derived classes share many of the same properties but the base class that they are derived from doesn't. One such property example is .Parent which exists on a huge number of derived classes but not on the base class and it is this property that I need to use.
For ease of understanding I've created a small example as follows:
class StandardBaseClass {} // These are simulating the SMO objects
class StandardDerivedClass : StandardBaseClass {
public object Parent { get; set; }
}
static class Extensions
{
public static object GetParent(this StandardDerivedClass sdc) {
return sdc.Parent;
}
public static object GetParent(this StandardBaseClass sbc)
{
throw new NotImplementedException("StandardBaseClass does not contain a property Parent");
}
// This is the Generic function I'm trying to write and need the Parent property.
public static void DoSomething<T>(T foo) where T : StandardBaseClass
{
object Parent = ((T)foo).GetParent();
}
}
In the above example calling DoSomething() will throw the NotImplemented Exception in the base class's implementation of GetParent(), even though I'm forcing the cast to T which is a StandardDerivedClass.
This is contrary to other casting behaviour where by downcasting will force the use of the base class's implementation.
I see this behaviour as a bug. Has anyone else out there encountered this?
I see this behaviour as a bug.
This behavior is correct. Since your method DoSomething is constraining T to StandardBaseClass, you only have access to the specific methods of StandardBaseClass, not any methods or properties of a derived class. Since StandardBaseClass does not have a Parent property, this is invalid, and should be invalid, by design.
There are two potential options here - You can use reflection to pull out the Parent property, or use C# 4's dynamic type, and treat this as a dynamic object. Both bypass the standard type checking in the compiler, however, so will require you to do extra type checking at runtime to verify that the Parent property exists.
Create an interface that contains the Parent property. Have each class that has a Parent property implement that interace. You will then be able to create a generic method that accepts a parameter of type IHaveParent, and it will do the right thing.
For anyone that is interested an succinct answer to this situation is answered by Stephen Cleary on msdn here:
http://social.msdn.microsoft.com/Forums/en-AU/csharpgeneral/thread/95833bb3-fbe1-4ec9-8b04-3e05165e20f8?prof=required
To me this is a divergence in the class hierarchy. By this this I mean that either the base class has parent, or the derived classes with Parent are derived from an abstract child of the base.
Lol as John says, an interface as opposed to an abstract class is sufficient too.
You idea won't work because the compiler can never guarantee that the base class actually would have such a property. And it won't just select the "right" one based on if it has it or not.
The only way you can do this is using reflection and then test at runtime if the requested property exists on the inspected class. You have to judge yourself if that is a viable way to do for your project (reflection is slow and requires maximum rights).
This is correct, as the compiler only knows that it can bind to your type as a StandardBaseClass. The binding is not done at runtime (where it could potentially decide to use the StandardDerivedClass overload.
If you know that it's a StandardDerivedClass, then why not just cast it as such?
object Parent = ((StandardDerivedClass)foo).Parent;
It's a bit ugly, but you can accomplish this using a Registration system, where you register delegates for different possible derived classes that expose the 'shared' property/method and then use something like a Dictionary<Type,Func<SomeT>> to store the delegates. If you know all of the derived types ahead of time and don't have to load plug-ins or the like, you can also use the classic ugly if/else-if structure. Either way you're basically creating your own substitute for what should have been supported by the virtual method table.

invoking method declaration without reflection

I have a base class (order) with a set of sub classes (productorder, specialorder, partsorder etc).
Only Some of these sub classes implement a particular interface (ITrackingCustomer) which has a single method declaration (object getcustdetails()).
As part of my solution all of my orders are processed in a central place, i.e. any crud methods pass through a central layer. Within this central layer I want to do the following:
If order is of type ITrackingCustomer
Then invoke method getcustdetails()
I have this working using the following code:
if (typeof(ITrackingCustomer).IsAssignableFrom(Order.GetType()))
{
MethodInfo theMethod = Order.GetType().GetMethod("getcustdetails");
object y = theMethod.Invoke(Order, null);
}
I am happy with the first part using isassignablefrom but would like to use a less performance intensive method for the second part (i.e. the reflection using invoke).
My question is:
Is there a more efficient way of doing this as I have read that using the invoke command is costly.
ITrackingCustomer ord = Order as ITrackingCustomer;
if (ord != null)
{
object y = ord.getcustdetails();
}
You can do:
if(Order is ITrackingCustomer) {
((ITrackingCustomer)Order).getcustdetails();
}
As others have mentioned, you can use the is and as operators to determine if an object is of a certain type. However, polymorphism is usually better suited for solving this type of problem.
If it is feasible, perhaps you can place a getcustdetails() method on Order. Make it virtual if it has a suitable default implementation (i.e. return no details or null), or abstract if it makes sense that all Order types must implement it. Since you have the ITrackingCustomer interface, I suspect that an abstract method won't work well. However, for Order types that implement ITrackingCustomer, you can then implement getcustdetails() accordingly.
At this point, it sounds like you would be able to do away with ITrackingCustomer, but I can't say for certain without knowing more details about how this interface is used.
Once this is done, you won't need to perform any type checks since calling Order.getcustdetails() always dispatches to the correct concrete implementation.
If you are trying to do call by name instead of invoking a member in an interface and you want to be able to call the same method thousands of times, then other than a cast (which I assume you can't do because you don't know the type) or reflection is to JIT compile the call.
Rick Strahl has a nice blog article on the performance costs of various ways to call method and the comments lead to this article which shows how to pull a delegate out to a non-virtual method.
Finally, I wrote a blog article on how to build adapter classes on the fly. What you can do with that is make a directly callable object that meets an abstract class:
public abstract class CustomerDetailsGetter {
public abstract object getcustdetails();
}
// ...
AdapterCompiler compiler = new AdapterCompiler();
AdapterFactory<CusomterDetailsGetter> factory = compiler.DefineAdapter<CustomerDetailsGetter>(Order.GetType());
// now, my code assumes you want to construct an object from whole cloth
// but the code could be changed to invoke the default constructor and set the
// adapted object.
CustomerDetailsGetter getter = factory.Construct(null)
object info = getter.getcustdetails();
Now, I need to be clear - there are only two reasons to do this:
you want to be able to have call-by-name semantics when you know the target arguments at compile time and you don't know have the target assembly, and you want your code to be CLEAN. An example of this is code that knows it wants to create and use a particular object, but doesn't know if the assembly will be available until run time and is forbidden to have a reference.
you want to call object methods a la reflection, but want to do this fast, fast, fast and will be calling them thousands or millions of times.
If it's a "call once" thing, you're way better off writing a helper method to do what you want.

Categories

Resources