C# public only for classes of the same interface - c#

Can I make some properties public only to same interface classes and readonly to all other classes?

You can use explicit implementation, for example:
interface IFoo {
int Value { get; set; }
}
public class Foo : IFoo {
public int Value { get; private set; }
int IFoo.Value {
get { return Value; }
set { Value = value; }
}
}
When accessed via Foo only the get will be accessible; when accessed via IFoo both getter and setter will be accessible.
Any use?

An interface is just something like a contract for classes. It doesn't change the accessibility level.
If a member of a class is public it is public to all classes that can access the class. The only restrictions you can have is the use of internal or protected. internal makes the member public to classes which are defined within the same assembly and protected makes it public to classes derived from the class.
Instead of the interface you can create an abstract base class and make the members protected:
public interface IFoo
{
int Value { get; set; }
}
public abstract class FooBase : IFoo
{
public abstract int Value { get; set; }
protected void ProtectedMethod()
{
}
}
public class Foo : FooBase
{
public int Value { get; set; }
}
However you can not define a member that is accessible by classes that implement a specific interface. There is no access modifier like public-to-IFoo-otherwise-private.

Related

Will change from abstract class to sealed class break simple client use

I'm changing a class from public abstract AwesomeClass, to public sealed AwesomeClass. I've also added a new property. All existing members are unchanged. I know that this is a breaking change. Clients that have implemented AwesomeClass or relied on it being abstract via reflection will be broken.
My question is, will clients that have only used members of instances of AwesomeClass that I've provided, be broken (and if yes how)? None of the clients will have a dependency on any of my types that implemented AwesomeClass as they were all internal. I think not, but...
Here is the class before and after:
public abstract class AwesomeClass
{
public abstract Guid SuperGuid { get; set; }
public abstract int SuperInt { get; set; }
}
public sealed class AwesomeClass
{
public Guid SuperGuid { get; set; }
public int SuperInt { get; set; }
public int OtherSuperInt { get; set; }
}
You mean that when you have this:
public abstract class Foo
{
public string Bar;
}
void UpdateFooBar(Foo foo)
{
foo.Bar = "Updated";
}
And you change abstract class Foo to sealed class Foo, will UpdateFooBar(Foo foo) continue to work?
What kept you from trying? But yes, it will.

Is it possible to have a private setter in base class set from derived class without being public?

Is it possible to give private access to a base class setter and only have it available from the inheriting classes, in the same way as the protected keyword works?
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass()
{
// Want to allow MyProperty to be set from this class but not
// set publically
public MyProperty = "abc";
}
}
public class MyBaseClass
{
public string MyProperty { get; private set; }
}
Why don't you use protected?
public string MyProperty { get; protected set; }
protected (C# Reference)
A protected member is accessible within its class and by derived class instances.
You only need to make the setter as protected like:
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass()
{
// Want to allow MyProperty to be set from this class but not
// set publically
MyProperty = "abc";
}
}
public class MyBaseClass
{
public string MyProperty { get; protected set; }
}
See also Access Modifiers (C# Reference)
Use protected instead of private.
Protected is the right approach, but for the sake of discussion, it's possible to set a private property this way:
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass() : base(myProperty: "abc") { }
}
public class MyBaseClass
{
public string MyProperty { get; private set; }
public MyBaseClass(string myProperty) {
this.MyProperty = myProperty;
}
}

Implementing an interface with interface members

What is the proper way to implement an interface that has its own interface members? (am I saying that correctly?) Here's what I mean:
public Interface IFoo
{
string Forty { get; set; }
string Two { get; set; }
}
public Interface IBar
{
// other stuff...
IFoo Answer { get; set; }
}
public class Foo : IFoo
{
public string Forty { get; set; }
public string Two { get; set; }
}
public class Bar : IBar
{
// other stuff
public Foo Answer { get; set; } //why doesnt' this work?
}
I've gotten around my problem using explicit interface implementation, but I'm wondering if there is a better way?
You need to use the exact same type as in the interface:
public class Bar : IBar
{
public IFoo Answer { get; set; }
}
Note: IFoo instead of Foo.
The reason is that the interface defines a contract and the contract says that it must be an IFoo.
Think about it:
You have the classes Foo and Foo2, both implement IFoo. According to the contract, instances of both classes can be assigned. Now, if your code was legal, this would somehow break because your class only accepts Foo. Explicit interface implementation doesn't change that fact in any way.
You'll need to use generics to be able to do what you want.
public interface IFoo
{
string Forty { get; set; }
string Two { get; set; }
}
public interface IBar<T>
where T : IFoo
{
// other stuff...
T Answer { get; set; }
}
public class Foo : IFoo
{
public string Forty { get; set; }
public string Two { get; set; }
}
public class Bar : IBar<Foo>
{
// other stuff
public Foo Answer { get; set; }
}
This will allow you to provide an interface that says something like, "to implement this interface you must have a property with a public getter/setter of a type that implements IFoo." Without generics you are simply saying that the class has a property with a type of exactly IFoo, rather than anything that implements IFoo.
IBar has a IFoo field, not a Foo one, do this instead:
public class Bar : IBar
{
// other stuff
public IFoo Answer { get; set; }
}
Foo may extend type IFoo but that isn't what the interface exposes.
An interface defines a contract and you need to obey the terms of that contract.
So the correct way is to use
public IFoo Answer{get;set;} like others have said.

Specifying multiple interfaces for a parameter

I have an object that implements two interfaces... The interfaces are:
public interface IObject
{
string Name { get; }
string Class { get; }
IEnumerable<IObjectProperty> Properties { get; }
}
public interface ITreeNode<T>
{
T Parent { get; }
IEnumerable<T> Children { get; }
}
such that
public class ObjectNode : IObject, ITreeNode<IObject>
{
public string Class { get; private set; }
public string Name { get; private set; }
public IEnumerable<IObjectProperty> Properties { get; set; }
public IEnumerable<IObject> Children { get; private set; }
public IObject Parent { get; private set; }
}
Now i have a function which needs one of its parameters to implement both of these interfaces. How would i go about specifying that in C#?
An example would be
public TypedObject(ITreeNode<IObject> baseObject, IEnumerable<IType> types, ITreeNode<IObject>, IObject parent)
{
//Construct here
}
Or is the problem that my design is wrong and i should be implementing both those interfaces on one interface somehow
public void Foo<T>(T myParam)
where T : IObject, ITreeNode<IObject>
{
// whatever
}
In C#, interfaces can themselves inherit from one or more other interfaces. So one solution would be to define an interface, say IObjectTreeNode<T> that derives from both IObject and ITreeNode<T>.
It's probably easiest to define an interface that implements both IObject and ITreeNode.
public interface IObjectNode<T> : IObject, ITreeNode<T>
{
}
Another option, in case you don't expect the above interface would be used often, is to make the method/function in question generic.
public void Foo<T>(T objectNode) where T : IObject, ITreeNode<IObject>
public void MethodName<TParam1, TParam2>(TParam1 param1, TParam2 param2)
where TParam1 : IObject
where TParam2 : ITreeNode<IObject>

C# explicit declare member interface

How to declare explicit a member of a interface?.i.e:
public interface IPerfil
{
int IDPerfil
{
get;
set;
}
int IDMarca
{
get;
set;
}
int IDRegional
{
get;
set;
}
int IDFilial
{
get;
set;
}
}
then
public class ComentariosPerfil : BaseComentarios, IPerfil
{
public int IPerfil.IDFilial
{
get;
set;
}
[...]
I get an compilation error,saying that "public" modifier cannot be applied to this item.
The question is:
I want this property to be public. I can't write modifiers in interface like:
public int IDPerfil
{
get;
set;
}
So,how can I explicitly implement an interface member, and make it Public?
For explicitly implemented interfaces you can't specify the visibility. It is taken from the visibility in the interface's definition.
So in your case use the following. The function will be public because that's the way the IPerfil interface is defined:
public class ComentariosPerfil : BaseComentarios, IPerfil
{
int IPerfil.IDFilial
{
get;
set;
}
No, you can't. Explicitly implemeting an interface means you have to cast it to the interface type first to use the defined contract. All members of an interface are public by default, so a public explicit interface doesn't make any sense because you can't access it from the implementing class in the first place.

Categories

Resources