How to hide implementation - c#

Lets say I have a class library, where any classes that are internal have access to the following interface:
interface myInterface
{
string myProperty { get; set; } // notice setter.
}
But if somebody adds this class library to their project they get the following interface:
public interface myInterface
{
string myProperty { get; }
}
What is the most efficient and accepted way of doing this? Have one interface implement the other?

Make your public interface have just the getter:
public interface myInterface
{
string myProperty { get; }
}
And then derive another internal-only interface from it that has a setter:
internal interface myInternalInterface : myInterface
{
new string myProperty { get; set; }
}
You can them implement the internal interface:
class myImplementation : myInternalInterface
{
public string myProperty{get; set;}
}
If you need to call the setter, you can cast your instance to the internal inteface and call it on that. This approach is a bit of a design smell though, so use it sparingly.

You can have the internal interface extend the public interface, like so:
public interface MyInternalInterface: MyPublicInterface
{
string MyProperty { set; }
}
public interface MyPublicInterface
{
string MyProperty { get; }
}
internal class A: MyInternalInterface
{
public string MyProperty { get; set; }
}
public class Foo
{
private A _a = new A();
internal MyInternalInterface GetInternalA() { return _a; }
public MyPublicInterface GetA() { return _a; }
}
This way you don't need any casts or anything.

I thought that #adrianbanks' answer might be an improvement on mine, however I don't think it really is (despite being nifty) - because you have no guarantee that a public interface instance being passed to you also implements the internal one - which is also true of this solution. There's also the thing that it only works if the implementing type is internal - which is no good if you want to supply public types as standard interface implementations or as bases for a hierarchy.
This is what I use. Given:
interface myInterface
{
string myProperty { get; set; }
}
public interface myPublicInterface
{
string myProperty { get; }
}
First you can't make myPublicInterface inherit myInterface because the compiler will moan about inconsistent accessibility. So you can explicitly implement the internal one, using a property backer, and then implement the public one implicitly:
public class MyClass : myInterface, myPublicInterface
{
private string _myProperty;
string myInterface.myProperty
{
get { return _myProperty; }
set { _myProperty = value; }
}
public string myProperty
{
get { return _myProperty; }
}
}
Note - in some cases, the getter might not be suitable for a private backer, but might be some logic that calculates values from other properties. In which case - to keep it DRY - you can put the logic in the public getter, and leech that for the explicit getter:
string myInterface.myProperty
{
get { return MyProperty; }
set { /*whatever logic you need to set the value*/ }
}
public string myProperty
{
get { /*whatever complex logic is used to get the value*/ }
}
You can do it the other way around, but you have to do a horrible-looking inline cast to the internal interface:
string myInterface.myProperty
{
get { /*whatever complex logic is used to get the value*/ }
set { /*whatever logic you need to set the value*/ }
}
public string myProperty
{
get { return ((myInterface)this).myProperty; }
}
Which you should try to steer clear of wherever possible.

Related

Enforce getter setter access at the interface level

I want to enforce access on getter or setter for a property at the interface level so that the same be followed in the class that implements it. I want to do something like below:
public interface IExample
{
string Name
{
get;
internal set;
}
}
public class Example : IExample
{
private string _name = String.Empty;
string Name
{
get
{
return _name;
}
internal set
{
_name = value;
}
}
}
But unfortunately from what I know this is not allowed in C#. I think that is because interface are meant to only expose what that is with a public access(I haven't the slightest idea!).
What I need here is a way to implement this using any other coding pattern (preferably using interface) which will help me to enforce specific access on getter or setter of a property in all of its implemented classes.
I googled this and tried to go through MSDN docs for this but had no luck!
Using internal on a setter is somewhat nasty anyway but if you really want to do it you could define a second interface that is itself internal AND make Example internal to your assembly.
public interface IExample
{
string Name
{
get;
}
}
internal interface IExampleInternal
{
string Name
{
set; get;
}
}
internal class Example : IExample, IExampleInternal
{
public string Name { get; set; } = string.Empty;
}
Now anything in the same assembly can take an IExampleInternal and outside only ever gets to see IExample. You do however have to list both interfaces on every class you create.
How about this? This can be a workaround:
// Assembly: A
public interface IExample
{
string Name { get; }
}
// Assembly: B
using A;
public abstract class Example : IExample
{
public string Name { get; protected internal set; }
}
public class SpecificExample : Example
{
public void UpdateName(string name)
{
// Can be set because it has protected accessor
Name = name;
}
}
class Program
{
static void Main(string[] args)
{
IExample e = new SpecificExample()
{
// Can be set because it has internal accessor
Name = "OutsideAssemblyA"
};
}
}
// Assembly: C
using A;
public abstract class Example : IExample
{
public string Name { get; protected internal set; }
}
public class AnotherSpecificExample : Example
{
public void UpdateName(string name)
{
// Can be set because it has protected accessor
Name = name;
}
}
class Program
{
static void Main(string[] args)
{
IExample e = new AnotherSpecificExample()
{
// Can be set because it has internal accessor
Name = "OutsideAssemblyA"
};
}
}
This works but you have to create (or copy-paste) the abstract class Example in every assembly in which you would like to create a specific implementation of it, e.g. SpecificExample or AnotherSpecificExample.
this is not possible. As everybody told you, interfaces are meant to define public access. How about the following code ?
public interface IExample
{
string Name
{
get;
}
}

C# Casting generics type to right type

I have this classes and interfaces:
public class XContainer
{
public List<IXAttribute> Attributes { get; set; }
}
public interface IXAttribute
{
string Name { get; set; }
}
public interface IXAttribute<T> : IXAttribute
{
T Value { get; set; }
}
public class XAttribute<T> : IXAttribute<T>
{
public T Value { get; set; }
}
I need to iterate over XContainer.Attributes and get property Value but I need to cast IXAttribute to correct generic representation like XAttribute<string> or XAttribute<int> but I don't want to use if-else if-else statement to check it like if XContainerl.Attributes[0] is XAttribute<string> then cast...
Is here a better way to do it?
There is a better way to do it.
Assuming you want to keep the current overall design, you could alter your non-generic interface and implementation as follows:
public interface IXAttribute
{
string Name { get; set; }
object GetValue();
}
public class XAttribute<T> : IXAttribute<T>
{
public T Value { get; set; }
public object GetValue()
{
return Value;
}
}
Then your iterator would just access GetValue(), no casting needed.
That said, I think the design might not be the best for what you're doing.
You could also define a generic extension method
public static class XAttributeExtensions
{
public T GetValueOrDefault<T>(this IXAttribute attr)
{
var typedAttr = attr as IXAttribute<T>;
if (typedAttr == null) {
return default(T);
}
return typedAttr.Value;
}
}
Then you can call it with (assuming T is int)
int value = myAttr.GetValueOrDefault<int>();
The reason for implementing it as an extension method is that it will work with any implementation of the non generic interface IXAttribute.

Interface for two almost identical web references in C#

I have 2 web refs which I can't change:
They are almost identical but when referenced one only accepts ProperCase and the other Uppercamelcase.
Example
Not only props is the thing but entire classes with its props and methods
#EDIT: Sorry, I've realized it's more complicated than initially stated:
Not only props is the thing but entire classes with its props and methods and inner classes. Although only used as structures, inner classes have the same issue.
public class Foobar
{
public string Logmsgno;
public string Revno;
public string Reqsox;
public void Dosomething();
public Barbaz Mybarbaz;
public List<quux> Myquuxlist;
}
And the other has names like
public class FooBar
{
public string LogMsgNo;
public string RevNo;
public string ReqSox;
public void DoSomething();
public BarBaz MyBarBaz;
public List<Quux> MyQuuxList;
}
Is there an easy way to make an interface for both?
TIA!
Without a proper re-factoring to update everything and changing names, yes, you COULD with a little bit of smoke and mirrors. Create an interface based on the NEW values you WANT them to be, then change them to respectively use getter/setter to retain original and not break it.
To expand from your expanded question. You would have to adjust each of those levels too.. Define an interface for the "Barbaz" and "BarBaz" class so your outer class can have an object of
public interface IYourBarBazInterface
{
string BarBazProp1 { get; set; }
string AnotherProp { get; set; }
}
public interface IQuux
{
int QuuxProp { get; set; }
string AnotherQuuxProp { get; set; }
}
public interface IYourCommonInterface
{
string LogMsgNo { get; set; };
string RevNo { get; set; };
string ReqSox { get; set; };
// Similar principle of declarations, but interface typed objects
IYourBarBazInterface MyBarBaz { get; set; }
List<IQuux> MyQuuxList;
void DoSomething();
}
public class Foobar : IYourCommonInterface
{
public string Logmsgno;
public string Revno;
public string Reqsox;
public void Dosomething();
// your existing old versions keep same name context
// but showing each of their respective common "interfaces"
public IYourBarBazInterface mybarbaz;
public List<IQuux> myQuuxlist = new List<IQuux>();
// these are the implementations of the interface...
public string LogMsgNo
{ get { return Logmsgno; }
set { Logmsgno = value; }
}
public string RevNo
{ get { return Revno; }
set { Revno = value; }
}
public string ReqSox
{ get { return Reqsox; }
set { Reqsox = value; }
}
public void DoSomething()
{ Dosomething(); }
// Now, the publicly common Interface of the "IYourCommonInterface"
// that identify the common elements by common naming constructs.
// similar in your second class.
public IYourBarBazInterface MyBarBaz
{ get { return mybarbaz; }
set { mybarbaz = value; }
}
public List<IQuux> MyQuuxList
{ get { return myQuuxlist; }
set { myQuuxlist = value; }
}
}
public class FooBar : IYourCommonInterface
{
// since THIS version has the proper naming constructs you want,
// change the original properties to lower case start character
// so the interface required getter/setter will be properly qualified
public string logMsgNo;
public string revNo;
public string reqSox;
public IYourBarBazInterface MyBarbaz;
public List<IQuux> Myquuxlist;
// these are the implementations of the interface...
public string LogMsgNo
{ get { return logMsgMo; }
set { logMsgNo = value; }
}
public string RevNo
{ get { return revNo; }
set { revNo = value; }
}
public string ReqSox
{ get { return reqSox; }
set { reqSox = value; }
}
// Since your "DoSomething()" method was already proper case-sensitive
// format, you can just leave THIS version alone
public void DoSomething()
{ .. do whatever .. }
public IYourBarBazInterface MyBarBaz
{ get { return MyBarbaz; }
set { MyBarbaz = value; }
}
public List<IQuux> MyQuuxList
{ get { return myquuxlist; }
set { myquuxlist = value; }
}
}
Unfortunately, no. There's not. C# is case sensitive (including interfaces). To have them both conform to a single interface, the name case would have to match. If you did that, the classes would be the same anyway.
Your only option would be to create an interface that used one of the casing methods, implement it on both classes, and then add code to one class (with the naming convention you didn't chose) to pass through the calls:
public interface IFooBar
{
string LogMsgNo { get; set; }
string RevNo { get; set; }
string ReqSox { get; set; }
void DoSomething();
}
public class Foobar : IFooBar
{
public string Logmsgno;
public string Revno;
public string Reqsox;
public void Dosomething();
public string LogMsgNo
{
get { return Logmsgno; }
set { Logmsgno = value; }
}
// And so on
}
UPDATE
After seeing your edit, things become much more complex. You'll have to do the same thing to all of the inner classes and then have your interfaces reference the lower level interfaces. Same concept, just more work.
If I had to handle this, I would likely write an extension method to convert from one type to another. Some reflection would do most of the work. new Foobar().ToFooBar().ToFoobar() Or write a class I would always interact with and at the last point you need to access the right implementation, call the ToFoobar().

Explicit Interface Implementation and Multiple Interfaces

In some locations of my program I need access to the concrete implementation of an object (Test) and in other locations I only need a read-only interface (ITest). This is to prevent an user from assuming that all properties are set and modifiable
For example if the user calls TestFactory.Search the returned collection will prevent them from modifying the property A and using CollectionB (it is not set inside the function). I would like to be able to use object initializers and keep the properties names the same. I have the following solution:
public interface IReadOnly
{
int Id{ get; }
string Name{ get; }
}
public class ClassA : IReadOnly
{
int Id{ get; internal set; }
string Name{ get; set; }
}
public interface ITest
{
int Id{ get; }
IReadOnly A { get; }
}
public class Test : ITest
{
private ClassA classA = new ClassA();
int Id{ get; internal set; }
IReadOnly ITest.A{ get{ return classA; } }
public ClassA A
{
get
{
return classA;
}
set
{
classA = value;
}
}
public IEnumerable<string> CollectionB {get;set;}
}
public static class TestFactory
{
IEnumerable<ITest> Search(){ /**/ }
Test Read(){ /**/ };
}
Is there a better way to solve this problem and is the abusing the concept of explicit interface implementation?
I would have your Test class implement both interfaces, IReadOnly and ITest. When you want to restrict setter access, cast to IReadOnly, otherwise, use ITest or the concrete Test.
Maybe create an abstract class instead and then subclass the full access and read only behavior?

When implementing an interface which define a base class property why can't the class implementing interface return a derived class type object?

Lets create some interfaces
public interface ITimeEventHandler
{
string Open();
}
public interface IJobTimeEventHandler : ITimeEventHandler
{
string DeleteJob();
}
public interface IActivityTimeEventHandler : ITimeEventHandler
{
string DeleteActivity();
}
public interface ITimeEvent
{
ITimeEventHandler Handler { get; }
}
public interface IJobTimeEvent : ITimeEvent
{
int JobID { get; }
}
Create a class
public class JobTimeEvent : IJobTimeEvent
{
public int JobID
{
get; internal set;
}
public IJobTimeEventHandler Handler
{
get; internal set;
}
}
My question is .. when implementing an interface which define a base class property why cant the class implementing interface return a derived class type object ??
For ex in class JobTimeEvent, IJobtimeEvent needs a property of type ITimeEventHandler but why IJobTimeEventHandler type is not allowed which derived from ITimeEventHandler
This is a duplicate of
Why C# doesn't allow inheritance of return type when implementing an Interface
The feature you want is called "return type covariance", and it is a frequently requested feature in C#. It is not supported by the CLR and we have no plans to implement it in C#, sorry!
Edit: The following is equally valid for get/set properties, so the fact that you can't declare fields in an interface is not fundamental to the points I'm making.
In your case, ITimeEvent.Handler is a field, which means you could do the following:
ITimeEvent x = ...;
IJobTimeEventHandler handler = ...;
x.Handler = handler;
If x was assigned an object of (concrete) type JobTimeEvent, and JobTimeEvent.Handler was declared as a JobTimeEventHandler, the the assignment above would fail. This is an example of how contravariance is not a safe operation for assignment.
If instead you had the following:
interface ITimeEvent
{
IJobTimeEventHandler Handler { get; }
}
Then you could easily do this:
class JobTimeEvent : ITimeEvent
{
private JobTimeEventHandler _handler;
public IJobTimeEventHandler Handler { get { return _handler; } }
}
It can return a class of this type, but it must satisfy the contract of the ITimeEvent interface and return it saying it's of type ITimeEventHandler. Suggest you use a property of this type, with a backing field of the derived type.
If you want the fields you definded to really be properties you could do something like this...
public interface ITimeEvent
{
ITimeEventHandler Handler { get; set; }
}
public interface IJobTimeEvent : ITimeEvent
{
int JobID { get; set; }
}
public class JobTimeEvent : IJobTimeEvent
{
public JobTimeEvent()
{
//these are currently useless because they are the default values
this.JobID = 0;
this.Handler = null;
}
public int JobID { get; set; }
public ITimeEventHandler Handler { get; set; }
}
... if you are trying to do something different you will need to provide more details to your question.

Categories