I have a class named Class1 and In this class I have a property named MyProperty. In another class I declare Class1 property but I want in this situation MyProperty be readonly. How can I do this?
public class Class1
{
public int MyProperty { get; set; }
}
public class Class2
{
public Class1 Class1Property { get; }
}
public class Class3
{
void Method()
{
Class2 obj = new Class2();
obj.Class1Property.MyProperty = 2;//I want this be illegal (In this place only)
}
}
Do some further abstraction and create an interface for Class1:
public interface IClass1
{
int MyProperty { get; }
}
Then make Class1 implement this interface:
public class Class1 : IClass1
{
public int MyProperty { get; set; }
}
Class2 should not expose a Class1 instance, but an instance of IClass1:
public class Class2
{
public IClass1 Class1Property { get; }
}
Now you got the behaviour you want:
public class Class3
{
void Method()
{
Class2 obj = new Class2();
obj.Class1Property.MyProperty = 2; // Doesn't work.
}
}
Class1 has decided that MyProperty is modifiable, no matter how you obtain a Class1, so what you want simply is not possible.
There are some ways that you can re-work your design, though. This is the approach I would take:
public class ReadOnlyClass1
{
public int MyProperty { get; protected set; }
}
public class Class1 : ReadOnlyClass1
{
public new int MyProperty {
get { return base.MyProperty; }
set { base.MyProperty = value; }
}
}
Now, you can give Class3 a property of type ReadOnlyClass1.
There are a couple ways to do this, the easiest as mentioned in the comments is by making the setter of "MyProperty" private:
public int MyProperty { get; private set; }
You can also try another access modifier that better suits your need.
Just think what the get and set mean: When being compiled, a Getter and Setter method gets created much like it was implemented in java.
You can also create the property with just a "get" and implement the "set" functionality outside of the property itself (like in the class constructor, in an internal method or something like that).
public int myProperty{get;private set;}//this is read only property
obj.Class1Property.MyProperty = 2;//this is illegal
Related
Say I have the following classes:
public abstract class A
{
protected abstract ReturnA Foo();
public void UseFoo()
{
var foo = Foo();
if (foo != null)
{
//logic here
}
}
}
public class B : A
{
protected override ReturnA Foo()
{
// Implementation specific code that returns ReturnB instead.
}
}
public class C : A
{
protected override ReturnA Foo()
{
// Implementation specific code that returns ReturnC instead.
}
}
public class ReturnA
{
public int Id { get; set; }
public string Address { get; set; }
}
public class ReturnB
{
public string Id { get; set; }
public string PhoneNumber { get; set; }
}
public class ReturnC
{
public Guid Id { get; set; }
public string Name { get; set; }
}
I know that C# does not support derived return types, but this is not what I need either.
Classes B and C are implementation specific and therefore their return types have nothing to do with eachother.
The reason why I would want to handle this, is because the method UseFoo in class A may have some generic checks and other generic logic, that has nothing to do with the returned object itself.
So I want to "outsource" only the code that is implementation specific and not have to instead make UseFoo abstract and have every implementation write the same generic code.
Is there any way to solve this at all?
EDIT: Neither ReturnC nor ReturnB are derived from ReturnA. Updated with examples.
This is a huge design problem that I often encounter and I think it is because I don't understand OOP right.
Here is the class of the base Property :
public class BasePropety {}
Here is the type of my DerivedProperty:
public class DerivedProperty : BaseProperty
{
public AClass A { get; set; }
}
Here is my base class :
public class BaseClass
{
public BaseProperty Property { get; set; }
}
Here my derived class :
public class DerivedClass : BaseClass
{
public DerivedProperty Property { get; set; }
public void MethodExample()
{
AClass aValue = this.Property.A;
}
}
I could of course typecast my property but it is annoying:
public class DerivedClass : BaseClass
{
public void MethodExample()
{
var typedProperty = (DerivedProperty) this.Property;
AClass aValue = typedProperty.A;
}
}
I know I can use the new keyword but I read here and there that it is a bad practice, so how I am suppose to achieve this ? Should I create a new property ?
Thanks in advance for your answers.
Sounds like you need generics instead:
public class BaseClass<T> where T : BaseProperty
{
public T Property { get; set; }
}
public class DerivedClass : BaseClass<DerivedProperty>
{
public void MethodExample()
{
AClass aValue = Property.A;
}
}
Note that this means there's only one property - whereas in your current code, you actually have two independent properties, which happen to have the same name. I suspect you don't want that.
I've tried to learn the short version of get & set in C#, but I don't know how to use them.
This is what I tried:
namespace SomeNamespace {
class SomeClass {
private int field1 { get; set;}
private int field2 { public get; public set; }
}
class OtherClass {
SomeClass sc = new SomeClass();
int field1 = sc.field1; //it doesn't work
int field2 = sc.field2; //it also doesn't work
sc.field1 = 1; //same here
sc.field2 = 2; //and here
}
}
In my SomeClass object I don't have access to any field nor "special" method to do this.
I obviously don't get it, so please help me to understand.
You need to use the accessors the other way around on your properties if you want to only allow read access on your property from outside classes:
public int field2 { get; private set; }
// setting only allowed from SomeClass, not from OtherClass or inheritors
To allow inheritors, you need to set private to protected.
If you want to allow both read and write from outside classes:
public int field2 { get; set; }
// setting allowed from any class
You need to declare them as public. Like following.
namespace SomeNamespace {
class SomeClass {
public int field1 { get; set;}
public int field2 { get; set;}
}
class OtherClass {
SomeClass sc = new SomeClass();
// frist set the values
sc.field1 = 1;
sc.field2 = 2;
// then read them
int field1 = sc.field1;
int field2 = sc.field2;
}
}
In C# 3.0 and later, auto-implemented properties make
property-declaration more concise when no additional logic is required
in the property accessors. They also enable client code to create
objects. When you declare a property as shown in the following
example, the compiler creates a private, anonymous backing field that
can only be accessed through the property's get and set accessors.
There are advantage of having getter/setter ( in comparison to just public variables).
Set accessibility via private set; etc..
You can add validation while setting the value or format while getting the value.
You can use them as part of an interface definition or an abstract class.
SOUREC - http://msdn.microsoft.com/en-us/library/bb384054.aspx
public class SomeClass
{
//Will be accessible by instance of this class
public int Field1 { get; set; }
//Accessible within class methods only
private int Field2 { get; set; }
public void SomeMethod()
{
//You can use private property in any of method within class only
Console.WriteLine(Field2);
}
//Accessible from derived class
protected int Field3 { get; set; }
}
public class SomeDerived : SomeClass
{
public void SomeDerivedFunction()
{
//Accessing baseclass Property
Console.WriteLine(Field3);
}
}
public class SomeThirdPartyClass
{
private SomeClass sc;
public SomeThirdPartyClass()
{
sc = new SomeClass();
//Field one as public accessible in other classes by instance
Console.WriteLine(sc.Field1);
}
}
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.
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?