limit method to only be called by a particular class - c#

I want a particular method in one class to only be accessible by a particular class. For example:
public class A
{
public void LimitedAccess() {}
public void FullAccess() {}
}
public class B
{
public void Func()
{
A a = new A();
a.LimitedAccess(); // want to be able to call this only from class B
}
}
public class C
{
public void Func()
{
A a = new A();
a.FullAccess(); // want to be able to call this method
a.LimitedAccess(); // but want this to fail compile
}
}
Is there is a keyword or attribute that I can use to enforce this?
UPDATE:
Due to existing system complexity and time constraints, I needed a low impact solution. And I wanted something to indicate at compile time that LimitedAccess() could not be used. I trust Jon Skeet's answer that exactly what I had asked for could not be done in C#.
The question and Jon's answer are good for those who may run across this later. And the fact that this design smells can hopefully veer anyone away for choosing something like this as a desired a solution.
As mentioned in a comment, the C# friend conversation is useful reading if you are trying to solve a similar situation.
As for my particular solution: "why would A contain B's logic" (asked by #sysexpand in comments). That's the rub. B.Func() was called throughout the system I'm working on, but it primarily operated on a singleton of A. So what I ended up doing was moving B's Func() into A and making A.LimitedAccess() private. There were a few other details to work around, as there always are, but I got a low impact solution that gave me compile-time errors on callers to A.LimitedAccess().
Thanks for the discussion.

No. The only thing you could do would be to make LimitedAccess a private method, and nest class B within class A.
(I'm assuming you want all the classes in the same assembly. Otherwise you could put A and B in the same assembly, and C in a different assembly, and make LimitedAccess an internal method.)

Yes. What you are asking for is perfectly possible.
You can restrict access to methods and variables for a specific instance, by using an interface.
However, an interface alone cannot prevent someone from creating their own instance of the class, at which point they will have full access to that instance.
To do that, next you should nest it as a private class inside of another class in order to restrict access to the constructor.
Now you have a particular method in one class to only be accessible by a particular class.
In this example, only class B is ever able to access function LimitedAccess.
public interface IA
{
void FullAccess();
}
public class B
{
private class A : IA
{
public void LimitedAccess() {} //does not implement any interface
public void FullAccess() {} //implements interface
}
private A a = new A();
public IA GetA()
{
return (IA)a;
}
public void Func()
{
/* will be able to call LimitedAccess only from class B,
as long as everybody else only has a reference to the interface (IA). */
a.LimitedAccess();
}
}
//This represents all other classes
public class C
{
public void Func(IA ia)
{
ia.FullAccess(); // will be able to call this method
ia.LimitedAccess(); // this will fail to compile
}
}
public static class MainClass
{
public static void Main(string[] args)
{
B b = new B();
b.Func();
IA ia = b.GetA();
C c = new C();
c.Func(ia);
}
}

In case you just want to remind yourself (or team mates) to not call LimitedAccess everywhere, you could consider using explicit interface implementation or mark LimitedAccess as obsolete.
public interface IA
{
void LimitedAccess();
void FullAccess();
}
public class A : IA
{
private void LimitedAccess() { }
public void FullAccess() { }
void IA.LimitedAccess() => LimitedAccess();
void IA.FullAccess() => FullAccess();
}
public class B
{
public void Func()
{
IA a = new A();
a.LimitedAccess(); // want to be able to call this only from class B
}
}
public class C
{
public void Func()
{
A a = new A();
a.FullAccess(); // want to be able to call this method
a.LimitedAccess(); // -> fails to compile
}
}

Maybe this is a workaround.
Use the System.Runtime.CompilerServices and then you can either check the Name of the calling function and/or the file, in which the calling function is defined. If you have a class per file, the filename might be a substitude for the class name. Check it and block the call.
internal void MySecretFunction (string something,
[CallerMemberName] string memberName = null,
[CallerFilePath] string filePath = null,
[CallerLineNumber] int lineNumber = 0) {
if (!filePath.EndsWith(#"\goodClass.cs")) return;
// else do something
}

You could always see the calling type with a StackTrace.
Just note that when building in release mode, the call on the stack will get optimized, and its possible that the stack trace could return a completely different class, so just make sure to test it before you publish.
/// <summary>
/// Warning: Any class that calls this other than "B" will throw an exception.
/// </summary>
public void LimitedAccess()
{
if (new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType != typeof(B)) throw new Exception("Invalid Caller Type, B is only class able to call this method.");
}
Unfortunately you wont be able to know if its an error on compile time. Best you can do is throw an exception if it gets called, and add a comment warning people about it.

It is against OOP best practices to make such a design. Methods of classes are not supposed to be protected from being called.
If your design requires control over calling a method, then control should be exercised by testing the arguments - caller which is authorized to make a call would "know" the magic word to pass as the argument.

This is a variation of the solution suggested by #cowlinator using class AWithUnlimitedAccess derived from class A rather than class A implementing interface IA.
The result and the limitations are the same, but I like it better because (1) the limited access methods are defined inside its own class and (2) it's easier to add documentation comments.
public class A
{
public void FullAccess() { }
}
public class AWithUnlimitedAccess : A
{
public void LimitedAccess() { }
}
public class B
{
private AWithUnlimitedAccess a = new AWithUnlimitedAccess();
public A GetA()
{
return a;
}
public void Func()
{
a.FullAccess();
a.LimitedAccess();
}
}
// This represents all other classes
public class C
{
public A A;
public void Func()
{
A.FullAccess();
A.LimitedAccess(); // this will fail compile
}
}
public static class MainClass
{
static void Main(string[] args)
{
B b = new B();
b.Func();
C c = new C();
c.A = b.GetA();
c.Func();
}
}

Related

C#: Giving access to private members without 3-fold code duplication

I have a class
public class Foo{
public Foo{...}
private void someFunction(){...}
...
private Acessor{
new Acessor
}
}
with some private functionality (someFunction). However, sometimes, I want to allow another class to call Foo.SomeFunction, so I have an inner class access Foo and pass out that:
public class Foo{
public Foo{...}
private void someFunction(){...}
...
public Acessor{
Foo _myFoo;
new Acessor(Foo foo){_myFoo = foo;}
public void someFunction(){
_myFoo.someFunction();
}
}
}
With this code, if I want a Foo to give someone else pemission to call someFunction, Foo can pass out a new Foo.Accessor(this).
Unfortunately, this code allows anyone to create a Foo.Accessor initiated with a Foo, and they can access someFunction! We don't want that. However, if we make Foo.Accessor private, then we can't pass it out of Foo.
My solution right now is to make Acessor a private class and let it implement a public interface IFooAccessor; then, I pass out the Foo.Accessor as an IFooAccessor. This works, but it means that I have to declaration every method that Foo.Accessor uses an extra time in IFooAccessor. Therefore, if I want to refactor the signature of this method (for example, by having someFunction take a parameter), I would need to introduce changes in three places. I've had to do this several times, and it is starting to really bother me. Is there a better way?
If someFunction has to be accessible for classes in the same assembly, use internal instead of private modifier.
http://msdn.microsoft.com/en-us/library/7c5ka91b(v=vs.71).aspx
If it has to be accessible for classes which are not in the same assemble then, it should be public. But, if it will be used by just a few classes in other assemblies, you probably should think better how you are organizing you code.
It's difficult to answer this question, since it's not clear (to me at least) what exactly you want to achieve. (You write make it difficult for someone to inadverdantly use this code in a comment).
Maybe, if the method is to be used in a special context only, then explicitly implementing an interface might be what you want:
public interface ISomeContract {
void someFunction();
}
public class Foo : ISomeContract {
public Foo() {...}
void ISomeContract.someFunction() {...}
}
This would mean, that a client of that class would have to cast it to ISomeContract to call someFunction():
var foo = new Foo();
var x = foo as ISomeContract;
x.someFunction();
I had a similar problem. A class that was simple, elegant and easy to understand, except for one ugly method that had to be called in one layer, that was not supposed to be called further down the food chain. Especially not by the consumers of this class.
What I ended up doing was to create an extension on my base class in a separate namespace that the normal callers of my classes would not be using. As my method needed private access this was combined with explicit interface implementation shown by M4N.
namespace MyProject.Whatever
{
internal interface IHidden
{
void Manipulate();
}
internal class MyClass : IHidden
{
private string privateMember = "World!";
public void SayHello()
{
Console.WriteLine("Hello " + privateMember);
}
void IHidden.Manipulate()
{
privateMember = "Universe!";
}
}
}
namespace MyProject.Whatever.Manipulatable
{
static class MyClassExtension
{
public static void Manipulate(this MyClass instance)
{
((IHidden)instance).Manipulate();
}
}
}

How avoid 'If cascade' and type casting by using polymorphism?

Let's assume the following class structure with base class BC and 2 derived classes DC_A and DC_B;
Furthermore there is a class XY with a methode goo() with a parameter of type BC and other methodes
// base class
public class BC
{
public virtual void foo();
}
// derived class A
public class DC_A : BC
{
public override void foo() {}
}
// derived class B
public class DC_B : BC
{
public override void foo() {}
}
public class XY
{
public void goo(BC o)
{
// perfectly fine using polymorphism; no Ifs' no casting, OOP at its best ;-)
o.foo();
// but what to do here?
if ( (o as DC_A) != null )
{
doX(o as DC_A);
}
else if ((o as DC_B) != null)
{
doY(o as DC_B);
}
}
private void doX(DC_A o) {}
private void doY(DC_B o) {}
}
In 'Is passing around value objects using polymorphism a bad practice?' the Visitor pattern is proposed;
The problem of the If cascade and the casting is moved (not eliminated) into the abstract base class.
Are there better solutions to completely avoid the if's?
Its no option for me (in this example) to move the functionality from doX/doY to class DC_A/DC_B
Your advice is much appreciated.
Edit:
The background of this question is a C# / WinForms application with a form to manage a "test rule" consisting of differenct sub entities like TestSpec with a collection of measurement types, test limits, and so on (my DC_A, DC_B classes) all derived from EntityBase (=BC from above)
The form sends an event to the controller that a sub entity has changed;
simplified PropertiesChanged(EntityBase o)
The controller calls the corresponding methode in the model class (methode goo in class XY from above) which is now responsible to do the businesslogic which is not only persisting the changed sub entity test limit but also e.g. creating a new test limit revision object, increasing a test spec revision, etc..
Maybe in this way
the generic approach of having a methode like PropertiesChanged(EntityBase o) should be changed to more specifing events from the form and specific event handler in controller and model class to handle "TestLimitChanged" etc.
But this special case has led me to the more generic or "philosophical" question about polymorphism at all ;-)
If you are using .NET 4 there is a possibility with overloading and dynamic type, maybe that is an alternativ for you.
class Program
{
static void Main(string[] args)
{
DC_A dca = new DC_A();
DC_B dcb = new DC_B();
XY xy = new XY();
xy.goo(dca);
xy.goo(dcb);
}
}
// base class
public abstract class BC
{
public abstract void foo();
}
// derived class A
public class DC_A : BC
{
public override void foo() { }
}
// derived class B
public class DC_B : BC
{
public override void foo() { }
}
public class XY
{
//public void goo<T>(T o) where T : BC
//{
// //dynamic dyn = Convert.ChangeType(o, o.GetType());
// //dynamic dyn = o;
// //gooi(dyn);
// gooi((dynamic)o);
//}
// http://smellegantcode.wordpress.com/2008/11/04/dynamic-typing-in-c-4-and-duck-generics/
public void goo<T>(T o) where T : BC
{
gooi((dynamic)o);
}
private void gooi(DC_A o)
{
o.foo();
doX(o);
}
private void gooi(DC_B o)
{
o.foo();
doY(o);
}
private void gooi(BC o)
{
o.foo();
}
private void doX(DC_A o) { }
private void doY(DC_B o) { }
}
My suggestion:
Expose your doX() and doY() methods so they can be called from implementations of DC_A and DC_B.
Add an abstract Do() method to BC.
Implement Do() in DC_A to call the exposed doX() method.
Implement Do() in DC_B to call the exposed doY() method.
Inside goo(), just call o.Do().
You could decouple things further by passing a delegate to DC_A and DC_B which they will call, instead of exposing doX() and doY(). It very much depends on the usage patterns.
However, this is only really very useful if you can add some value to the Do() implementations in the derived classes. If all Do() does is just call doX() or doY(), you don't really get any benefit from doing it this way.
So I'm going to agree with the other poster here that says just do the casting.
I don't think there's too much to worry about, once we fix a couple of things:
At the moment you're casting more than you need to
Only one of those ifs can be true, so you don't need an else
After that, we have:
// perfectly fine using polymorphism; no Ifs' no casting, OOP at its best ;-)
o.foo();
var dca = o as DC_A;
if (dca != null)
{
doX(dca);
}
var dcb = o as DC_B;
if (dcb != null)
{
doY(dcb);
}
which I'd say looks fine.
If you want to go further, you could change the implementations of doX and doY so that they return immediately if passed null; then you could just say
doX(o as DC_A);
doY(o as DC_B);

Optimally and elegantly performing certain behaviors based on types in a hierarchy

I am trying to optimize a certain part of my code, which happens to be in a tight performance loop. Mainly I am trying to learn new things which I can apply in the future. My implementation is very lengthy, so I will give a general example of what I am trying to achieve.
My question relates to this: C# 'is' operator performance, and especially to the chosen answer.
Say I have a class A. I also have a class B, which is derived from A. I have a list of type A (which contains a mix of A and B types). In a method where I process these items, I would like to achieve a certain behaviour based on the actual type of the object (not sure if this is the correct way of saying it. Please correct me wherever I say something wrong).
void Process(A item)
{
if (item is A)
{
DoBehavior((A)item); //I know the cast is redundant here, I'm just leaving
//it here for my explanation.
}
else if (item is B)
{
DoBehavior((B)item);
}
}
void DoBehaviour(A item)
{
//perform necessary behaviour for type A
}
void DoBehaviour(B item)
{
//perform necessary behaviour for type B
}
This is the way I currently do it. Note that I iterate over a list of type A, which contains A's and B's. Also, if you feel I did not provide enough code to clarify the situation, I'll gladly expand.
In the question I posted above: C# 'is' operator performance, I have learnt that I can rather change the structure to use an "as" operator, and completely get rid of the explicit cast.
B bItem = item as B;
if (bItem != null)
{
DoBehavior(bItem);
}
This is all good, however, in actuality I do not just have an A and a B, I also have a C, a D, and so on, all deriving from base class A. This will lead to many of these if statements, and they would have to be nested for best performance:
B bItem = item as B;
if (bItem != null)
{
DoBehavior(bItem);
}
else
{
C cItem = item as C;
if (cItem != null)
{
DoBehavior(cItem);
}
else
{
//and so on.
}
}
Now this is ugly. I like writing neat, elegant code, yet I am exceptionally bad at doing it (which often leads me to wasting time trying to just make things look a little better).
I hope this question is not to broad, but firstly I would like to know if there is a more optimal and clean solution at getting the type so that the relevant behavior is performed. If not, is there a cleaner way to use these 'as' operators than nesting it like this?
I suppose one alternative would be to move the behavior into the base class A, and then overriding it for each derived class. However, in a higher thinking sense, the behavior in this particular case of mine is not a behavior of the class A (or it's children), rather, it is some external class acting/behaving on it (which will behave differently for each type). If there is no better way to do it, I will strongly consider implementing it as I have explained now - but I would like some expert opinions on this.
I tried to keep this short, and may have left too much detail out. Let me know if this is the case.
I would strongly suggest that you avoid the "if..else if..else if.." path by programming to interfaces instead of referencing concrete classes.
To achieve this, first make the Process() method ignorant of the type of its parameter. Probably the parameter will end up being an interface like IDoSomething.
Next, implement Process() so that it won't call DoSomething() directly. You'll have to break DoSomething() in smaller chunks of code which will be moved into specific implementations of IDoSomething methods. The Process() method will blindly call these methods -- in other words, applying the IDoSomething contract to some data.
This could be tiresome the more convoluted DoSomething() is, but you'll have a much better separation of concerns, and will "open" Process() to any IDoSomething compatible type, without writing not even one more else.
Isn't that what polymorphism is all about ? A method that has different behavior depending on its type. And I'm fairly sure this would be faster than a "type switch".
And if you need to, you can also use function overloading (for your external processing), see the test program below:
using System;
using System.Collections.Generic;
public class A
{
public String Value
{
get;
set;
}
public A()
{
Value = "A's value";
}
public virtual void Process()
{
// Do algorithm for type A
Console.WriteLine("In A.Process()");
}
}
public class B : A
{
public int Health
{
get;
set;
}
public B()
{
Value = "B's value";
Health = 100;
}
public override void Process()
{
// Do algorithm for type B
Console.WriteLine("In B.Process()");
}
}
public static class Manager
{
// Does internal processing
public static void ProcessInternal(List<A> items)
{
foreach(dynamic item in items)
{
item.Process(); // Call A.Process() or B.Process() depending on type
ProcessExternal(item);
}
}
public static void ProcessExternal(A a)
{
Console.WriteLine(a.Value);
}
public static void ProcessExternal(B b)
{
Console.WriteLine(b.Health);
}
public static void Main(String[] args)
{
List<A> objects = new List<A>();
objects.Add(new A());
objects.Add(new B());
ProcessInternal(objects);
}
}
Note that this will only work with .Net 4.0 !
The best solution for the situation I found is to use a Double-Dispatch/Visitor pattern. I describe a situation where base class A is abstract, and concrete classes B and C inherit from A. Also, by making the DoBehavior method in the base class A abstract, we are forcing ourselves to make an implementation for it wherever we would need it, so if we expand this to add more types, we won't forget to add it's DoBehavior methods (seems unlikely that one would forget, but this behavior may be insignificant to the rest of the new type you add, and may be overlooked - especially if there are many of these behavior patterns)
interface IVisitor
{
void DoBehavior(B item);
void DoBehavior(C item);
}
abstract class A
{
abstract void DoBehavior(IVisitor visitor);
}
class B : A
{
override void DoBehavior(IVisitor visitor)
{
//can do some internal behavior here
visitor.DoBehavior(this); //external processing
}
}
class C : A
{
override void DoBehavior(IVisitor visitor)
{
//can do some internal behavior here
visitor.DoBehavior(this); //external processing
}
}
class Manager: IVisitor //(or executor or whatever. The external processing class)
{
public static void ProcessAll(List<A> items)
{
foreach(A item in items)
{
item.DoBehavior(this);
}
}
void DoBehavior(B item)
{
}
void DoBehavior(C item);
{
}
}
Thanks for contributing, everyone. Learnt a lot and got some good ideas from you all (it's worth it to read all the answers if you face a similar situation).
One simple solution would be to add a field in the base class specifying the class type.
class A
{
// Alternative
string typeName = this.GetType().Name;
public virtual string TypeName { get { return typeName; } }
public virtual string GetTypeName() { return "A"; }
}
class B : A
{
public override string GetTypeName() { return "B"; }
}
class C : A
{
public override string GetTypeName() { return "C"; }
}
class Executer
{
void ExecuteCommand(A val)
{
Console.WriteLine(val.GetType().Name);
switch (val.GetTypeName())
{
case "A": DoSomethingA(val as A); break;
case "B": DoSomethingB(val as B); break;
case "C": DoSomethingC(val as C); break;
}
}
private void DoSomethingC(C c)
{
throw new NotImplementedException();
}
private void DoSomethingB(B b)
{
throw new NotImplementedException();
}
private void DoSomethingA(A a)
{
throw new NotImplementedException();
}
}
You don't really need to use strings, but I prefer that option to using integer for the simple reason that you can't declare 2 class with the same name in the same namespace, therefor if you always return the name class, you have an automatic anti conflict mechanism.

Virtual Extension Methods?

I have a class that gets used in a client application and in a server application.
In the server application, I add some functionality to the class trough extension methods. Works great. Now I want a bit more:
My class (B) inherits from another class (A).
I'd like to attach a virtual function to A (let's say Execute() ), and then implement that function in B. But only in the server. The Execute() method would need to do stuff that is only possible to do on the server, using types that only the server knows about.
There are many types that inherit from A just like B does, and I'd like to implement Execute() for each of them.
I was hoping I could add a virtual extension method to A, but that idea doesn't seem to fly. I'm looking for the most elegant way to solve this problem, with or without extension methods.
No, there aren't such things as virtual extension methods. You could use overloading, but that doesn't support polymorphism. It sounds like you might want to look at something like dependency injection (etc) to have different code (dependencies) added in different environments - and use it in regular virtual methods:
class B {
public B(ISomeUtility util) {
// store util
}
public override void Execute() {
if(util != null) util.Foo();
}
}
Then use a DI framework to provide a server-specific ISomeUtility implementation to B at runtime. You can do the same thing with a central static registry (IOC, but no DI):
override void Execute() {
ISomeUtility util = Registry.Get<ISomeUtility>();
if(util != null) util.Foo();
}
(where you'd need to write Registry etc; plus on the server, register the ISomeUtility implementation)
You can use the new dynamic type functionality to avoid having to build a registry of types to methods:
using System;
using System.Collections.Generic;
using System.Linq;
using visitor.Extension;
namespace visitor
{
namespace Extension
{
static class Extension
{
public static void RunVisitor(this IThing thing, IThingOperation thingOperation)
{
thingOperation.Visit((dynamic)thing);
}
public static ITransformedThing GetTransformedThing(this IThing thing, int arg)
{
var x = new GetTransformedThing {Arg = arg};
thing.RunVisitor(x);
return x.Result;
}
}
}
interface IThingOperation
{
void Visit(IThing iThing);
void Visit(AThing aThing);
void Visit(BThing bThing);
void Visit(CThing cThing);
void Visit(DThing dThing);
}
interface ITransformedThing { }
class ATransformedThing : ITransformedThing { public ATransformedThing(AThing aThing, int arg) { } }
class BTransformedThing : ITransformedThing { public BTransformedThing(BThing bThing, int arg) { } }
class CTransformedThing : ITransformedThing { public CTransformedThing(CThing cThing, int arg) { } }
class DTransformedThing : ITransformedThing { public DTransformedThing(DThing dThing, int arg) { } }
class GetTransformedThing : IThingOperation
{
public int Arg { get; set; }
public ITransformedThing Result { get; private set; }
public void Visit(IThing iThing) { Result = null; }
public void Visit(AThing aThing) { Result = new ATransformedThing(aThing, Arg); }
public void Visit(BThing bThing) { Result = new BTransformedThing(bThing, Arg); }
public void Visit(CThing cThing) { Result = new CTransformedThing(cThing, Arg); }
public void Visit(DThing dThing) { Result = new DTransformedThing(dThing, Arg); }
}
interface IThing {}
class Thing : IThing {}
class AThing : Thing {}
class BThing : Thing {}
class CThing : Thing {}
class DThing : Thing {}
class EThing : Thing { }
class Program
{
static void Main(string[] args)
{
var things = new List<IThing> { new AThing(), new BThing(), new CThing(), new DThing(), new EThing() };
var transformedThings = things.Select(thing => thing.GetTransformedThing(4)).Where(transformedThing => transformedThing != null).ToList();
foreach (var transformedThing in transformedThings)
{
Console.WriteLine(transformedThing.GetType().ToString());
}
}
}
}
I would suggest something like the following. This code could be improved by adding support for detecting intermediate class hierarchy types that don't have a dispatch mapping and calling the nearest dispatch method based on the runtime hierarchy. It could also be improved by using reflection to detect overload of ExecuteInteral() and adding them automatically to the dispatch map.
using System;
using System.Collections.Generic;
namespace LanguageTests2
{
public class A { }
public class B : A {}
public class C : B {}
public static class VirtualExtensionMethods
{
private static readonly IDictionary<Type,Action<A>> _dispatchMap
= new Dictionary<Type, Action<A>>();
static VirtualExtensionMethods()
{
_dispatchMap[typeof(A)] = x => ExecuteInternal( (A)x );
_dispatchMap[typeof(B)] = x => ExecuteInternal( (B)x );
_dispatchMap[typeof(C)] = x => ExecuteInternal( (C)x );
}
public static void Execute( this A instance )
{
_dispatchMap[instance.GetType()]( instance );
}
private static void ExecuteInternal( A instance )
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
private static void ExecuteInternal(B instance)
{
Console.WriteLine( "\nCalled ToString() on: " + instance );
}
private static void ExecuteInternal(C instance)
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
}
public class VirtualExtensionsTest
{
public static void Main()
{
var instanceA = new A();
var instanceB = new B();
var instanceC = new C();
instanceA.Execute();
instanceB.Execute();
instanceC.Execute();
}
}
}
Virtual implies inheritance in a OOP way and extension methods are "just" static methods that through a bit a syntactic sugar the compiler allows you to pretend to call on an instance of the type of its first parameter. So no, virtual extension methods are out of the question.
Check out the answer by Marc Gravell for a possible solution to your problem.
You can implement a service register. Example (server side):
static IDictionary<Type, IService> serviceRegister;
public void ServerMethod(IBusinessType object)
{
serviceRegister[obect.GetType()].Execute(object);
}
What you need are rather services in your server, which implement server side functionality, instead of extension methods. I wouldn't put to much logic into extension methods.
Let me check: you have a class hierarchy inheriting from A, presumably structured according to your business domain. Then you want to add behaviours depending on where the classes execute. So far you've used extension methods, but now you find you cannot get them to vary with your class hierarchy. What kinds of behaviours are you attaching at the server?
If it's stuff like transaction management and security, policies implemented through dependency injection à la Marc's suggestion should work well. You could also consider implementing the Strategy pattern through delegates and lambdas, for a more limited version of DI. However, what's not clear is how client code currently uses your classes and their extension methods on the server. How dependent are other classes on how you add the server-side functionality? Are they server-side only classes that currently expect to find the extension methods?
In any case, it sounds like you're going to need a careful testability design and testing strategy since you are introducing variation along two simultaneous dimensions (inheritance hierarchy, execution environment). You are using unit testing, I trust? Check that whatever solution you choose (e.g. DI through configuration) interacts well with testing and mocking.

C# - using polymorphism in classes I didn't write

What is the best way to implement polymorphic behavior in classes that I can't modify? I currently have some code like:
if(obj is ClassA) {
// ...
} else if(obj is ClassB) {
// ...
} else if ...
The obvious answer is to add a virtual method to the base class, but unfortunately the code is in a different assembly and I can't modify it. Is there a better way to handle this than the ugly and slow code above?
Hmmm... seems more suited to Adapter.
public interface ITheInterfaceYouNeed
{
void DoWhatYouWant();
}
public class MyA : ITheInterfaceYouNeed
{
protected ClassA _actualA;
public MyA( ClassA actualA )
{
_actualA = actualA;
}
public void DoWhatYouWant()
{
_actualA.DoWhatADoes();
}
}
public class MyB : ITheInterfaceYouNeed
{
protected ClassB _actualB;
public MyB( ClassB actualB )
{
_actualB = actualB;
}
public void DoWhatYouWant()
{
_actualB.DoWhatBDoes();
}
}
Seems like a lot of code, but it will make the client code a lot closer to what you want. Plus it'll give you a chance to think about what interface you're actually using.
Check out the Visitor pattern. This lets you come close to adding virtual methods to a class without changing the class. You need to use an extension method with a dynamic cast if the base class you're working with doesn't have a Visit method. Here's some sample code:
public class Main
{
public static void Example()
{
Base a = new GirlChild();
var v = new Visitor();
a.Visit(v);
}
}
static class Ext
{
public static void Visit(this object b, Visitor v)
{
((dynamic)v).Visit((dynamic)b);
}
}
public class Visitor
{
public void Visit(Base b)
{
throw new NotImplementedException();
}
public void Visit(BoyChild b)
{
Console.WriteLine("It's a boy!");
}
public void Visit(GirlChild g)
{
Console.WriteLine("It's a girl!");
}
}
//Below this line are the classes you don't have to change.
public class Base
{
}
public class BoyChild : Base
{
}
public class GirlChild : Base
{
}
I would say that the standard approach here is to wrap the class you want to "inherit" as a protected instance variable and then emulate all the non-private members (method/properties/events/etc.) of the wrapped class in your container class. You can then mark this class and its appropiate members as virtual so that you can use standard polymorphism features with it.
Here's an example of what I mean. ClosedClass is the class contained in the assembly whose code to which you have no access.
public virtual class WrapperClass : IClosedClassInterface1, IClosedClassInterface2
{
protected ClosedClass object;
public ClosedClass()
{
object = new ClosedClass();
}
public void Method1()
{
object.Method1();
}
public void Method2()
{
object.Method2();
}
}
If whatever assembly you are referencing were designed well, then all the types/members that you might ever want to access would be marked appropiately (abstract, virtual, sealed), but indeed this is unfortunately not the case (sometimes you can even experienced this issue with the Base Class Library). In my opinion, the wrapper class is the way to go here. It does have its benefits (even when the class from which you want to derive is inheritable), namely removing/changing the modifier of methods you don't want the user of your class to have access to. The ReadOnlyCollection<T> in the BCL is a pretty good example of this.
Take a look at the Decorator pattern. Noldorin actually explained it without giving the name of the pattern.
Decorator is the way of extending behavior without inheriting. The only thing I would change in Noldorin's code is the fact that the constructor should receive an instance of the object you are decorating.
Extension methods provide an easy way to add additional method signatures to existing classes. This requires the 3.5 framework.
Create a static utility class and add something like this:
public static void DoSomething(this ClassA obj, int param1, string param2)
{
//do something
}
Add a reference to the utility class on the page, and this method will appear as a member of ClassA. You can overload existing methods or create new ones this way.

Categories

Resources