Is there a way to hide/show a method if a certain constructor is used? i.e.:
public class SomeClass
{
public SomeClass(string methodA)
{
}
public SomeClass(int methodB)
{
}
public string MethodA()
{
return "";
}
public int MethodB()
{
return 0;
}
}
if SomeClass(string methodA) is used, then only MethodA() is available when I instance a new SomeClass object? The same when SomeClass(int methodB) is used, then MethodB() would be available?
Thank you all!
No, it's not possible.
What's more likely is that you want to use generics:
public interface IFoo<T>
{
T Method();
}
public class IntFoo : IFoo<int>
{
int value;
public IntFoo(int value)
{
this.value = value;
}
public int Method()
{
return value;
}
}
public class StringFoo : IFoo<string>
{
string value;
public StringFoo(string value)
{
this.value = value;
}
public string Method()
{
return value;
}
}
If you don't need to restrict it to just strings or ints (or don't want to) then something like this might work, or even be better:
public class Foo<T>
{
private T value;
public Foo(T value)
{
this.value = value;
}
public T Method()
{
return value;
}
}
No. This is not possible. You'd be better off creating an abstract class, and creating two separate classes inheriting from the Abstract Class. Refer to Abstract Design Pattern.
You may be better off using generics for your class. It's a bit less fluid than you're probably looking for (because you have to define the type in the class declaration), but accomplishes what you mainly want, I think.
public class SomeClass<T>
{
public SomeClass(T value)
{
}
public T Method() { return default(T); }
}
Which means that creating an instance of the class would use "new SomeClass(0);" rather than simply "new SomeClass(0);"
Related
I have a base class called Message like this:
public abstract class Message
{
protected int m_id;
protected bool m_localized;
protected string m_metaData;
public int GetID() { return m_id; }
public bool GetLocalized() { return m_localized; }
public string GetMetadata() { return m_metaData; }
}
Then, i have two more classes that inherit from Message for example:
public class ClassicMessage : Message
{
private string m_title;
private string m_content;
public void SetTitle(string title) { m_title = title; }
public void SetContent(string content) { m_content = content; }
public string GetTitle() { return m_title; }
public string GetContent() { return m_content; }
}
public class MessageWithCustomContent : Message
{
private List<CustomContent> m_content;
public MessageWithCustomContent()
{
m_content = new List<CustomContent>();
}
public List<CustomContent> GetContent()
{
return m_content;
}
public CustomContent GetContentEntry(int id)
{
return m_content.find(x => x.ID.Equals(id));
}
}
public class CustomContent
{
private int m_id;
public int ID { get; set { m_id = value; } }
private string m_body;
public string Body { get { return m_body; } set { m_body = value; }
private Image m_image;
public Image Image { get { return m_image; } set { m_image = value; } }
}
In a case like this, how can i unify the app interface if the derived classes has similar methods but these methods have different return types? (even when the methods try to do the same)
I know that with the example i'm breaking the Liskov Substitution Principle and the Open/Closed principle, what's the best approach to get around with that?
Thanks for your help!
Edit:
For more clarity, what i'm trying to achieve is to create a common interface to manage all the possible messages as the base "Message", because i want to avoid using typeof in the consumer class.
for example:
if(message is MessageWithCustomContent)
{
// do something with the contents.
}
else if(message is MessageWithCustomContent)
{
// do another thing with the contents.
}
etc...
You could change Message to be generic, and the T would specify the Content return type. See example below.
Edit
You could use a "IMessage" and a "Message: IMessage" as base.
You would then be able to create a IMessage list like so
var messages = new List<IMessage>
{
new ClassicMessage(),
new MessageWithCustomContent()
};
foreach (var message in messages)
{
message.GetContent();
}
Below is how the implementation of IMessagecould be done.
public interface IMessage
{
int GetID();
bool GetLocalized();
string GetMetadata();
object GetContent();
}
public abstract class Message<T> : IMessage
{
protected int m_id;
protected bool m_localized;
protected string m_metaData;
public int GetID() { return m_id; }
public bool GetLocalized() { return m_localized; }
public string GetMetadata() { return m_metaData; }
object IMessage.GetContent()
{
return GetContent();
}
public abstract T GetContent();
}
public class ClassicMessage : Message<string>
{
private string m_title;
private string m_content;
public void SetTitle(string title) { m_title = title; }
public void SetContent(string content) { m_content = content; }
public string GetTitle() { return m_title; }
public override string GetContent()
{
return m_content;
}
}
public class MessageWithCustomContent : Message<List<CustomContent>>
{
private List<CustomContent> m_content;
public MessageWithCustomContent()
{
m_content = new List<CustomContent>();
}
public CustomContent GetCustomContent(int id)
{
return null;
}
public override List<CustomContent> GetContent()
{
return m_content;
}
}
public class CustomContent
{
private int m_id;
public int ID { get; set; }
private string m_body;
public string Body
{
get { return m_body; }
set { m_body = value; }
}
}
I will explain how you break LSP below but before I do that, you are not really doing any inheriting. Yes you are declaring your classes to be inheriting but you are not really inheriting anything. So before learning LSP, perhaps you need to get a grip on inheritance firstly.
How do I know if I am breaking LSP?
Lest say your Message class was like this, notice the virtual and abstract methods:
public abstract class Message
{
protected int m_id;
protected bool m_localized;
protected string m_metaData;
public virtual int GetID() { return m_id; }
public virtual bool GetLocalized() { return m_localized; }
public abstract string GetMetadata();
}
Create a list like this:
var messages = new List<Message>();
Then add concrete types to that list of all the inheriting types. Then do this:
foreach(var thisMessage in messages)
{
var id = thisMessage.GetID();
var loc = GetLocalized();
var meta = GetMetadata();
}
If you get no exception thrown because one of the inheriting classes decided it does not need one of those methods, then you have not broken LSP. The idea is that if something is inheriting Message, then it should inherit everything. Otherwise, we cannot safely and with confidence substitute the inherited one for the parent one.
The reason this principle is important is because there may be existing code which is using Message, as shown in the foreach above, where it is treating all the types polymorphically and a developer decides to inherit it like this:
public abstract class BadMessage
{
public override int GetID()
{
throw new InvalidOperationException
("This method is not needed for BadMessage and should not be called");
}
public override bool GetLocalized() { ... }
public override string GetMetadata() { ... }
}
You see this will break existing code. And the worst part is, the compiler will not even be able to catch it, until it surfaces like an ugly bug in production.
Well, you're missing the interface methods in de base class. Abstract functions, that get implemented in the derivative classes. If you get a Message, not knowing what kind it is, how would you request its contents?
You could add derivative-specific methods to your base, but you'd have to implement an not_implemented exception in a virtual implementation in the base class to compensate for all derivatives not implementing it, and add exception handling. But then you should ask yourself: " is this class really a derivative? What do I want to achieve."
I'm not that new to C# but don't have as much experience as in Java.
As you know, in Java, we can access all the private members from outer classes.
So I tried the same thing in C# because I had some fields and methods needed to be accessed from only inside my plugin library and didn't want it to be shown to users. A simple example can be like this.
public static class StaticClass {
public class InstanceClass {
private int oldValue;
public int Value;
}
public static void Backup(InstanceClass ic) {
ic.oldValue = ic.Value;
}
public static void Restore(InstanceClass ic) {
ic.Value = ic.oldValue;
}
}
If I make the field oldValue public, then it'll be mess and look dirty when end users use the plugin. It doesn't have to be an Inner class or in a some specific form. I just want to know if there is any way to control or access private members of an instance from other static classes in the same assembly only by me.
For allowing access only within assembly use internal modifier.
public class InstanceClass {
internal int oldValue;
public int Value;
}
This is not possible in C#. The container class has no special access over the nested class.
You can access private members of the container from the nested class, but not vice versa. The pattern you're trying to use simply isn't used in C# - it's a violation of member accessibility. There are some hacks to force the Java pattern on C# (using reflection or abusing interfaces), but they are just that - hacks.
The "cleanest" approach might look something like this:
public static class StaticClass
{
private interface IInstanceClassInternal
{
int OldValue { get; set; }
}
public sealed class InstanceClass : IInstanceClassInternal
{
int IInstanceClassInternal.OldValue { get; set; }
public int Value;
}
public static void Backup(InstanceClass ic)
{
((IInstanceClassInternal)ic).OldValue = ic.Value;
}
public static void Restore(InstanceClass ic)
{
ic.Value = ((IInstanceClassInternal)ic).OldValue;
}
}
It's obvious that you're trying to write Java in C# - the patterns, the coding style... That's probably a bad idea. Those static methods should probably be extension methods. The "hidden functionality in an object" doesn't quite sit with C#'s notion of OOP - your parent shouldn't have free access to your guts, it should only really have the same public interface everyone else has. After all, that's the whole point of LSP - such tight coupling is quite tricky for any extensibility. Why separate StaticClass from InstanceClass in the first place, if you want StaticClass to mess with InstanceClasses privates? Just make Backup and Restore public members of InstanceClass - or even a part of an interface (perhaps even through explicit implementation, if you want to "hide" it from users of InstanceClass).
You can use the internal access modifier, see https://msdn.microsoft.com/en-us/library/ms173121.aspx
Internal is only visible from inside the assembly
Example: https://dotnetfiddle.net/FNavfE
Have you tried to make it "internal"? It will be available in same dll but not external dll.
public class InstanceClass {
internal int oldValue;
public int Value;
}
Technically, you can use Reflection (if you insist on private field and a static class methods):
using System.Reflection;
...
public static void Backup(InstanceClass ic) {
if (null == ic)
throw new ArgumentNullException("ic");
ic.GetType()
.GetField("oldValue", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(ic, ic.Value);
}
public static void Restore(InstanceClass ic) {
if (null == ic)
throw new ArgumentNullException("ic");
ic.Value = (int) (ic.GetType()
.GetField("oldValue", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(ic));
}
however, a much better approach is to change access modifier from private to internal:
public class InstanceClass {
internal int oldValue;
public int Value;
}
Even better solution is to move both Backup and Restore methods into InstanceClass:
public class InstanceClass {
private int oldValue;
public int Value;
public void Backup() {
oldValue = Value;
}
public void Restore() {
Value = oldValue;
}
}
This field oldValue is an implementation detail of both StaticClass and InstanceClass. Lets make InstanceClass an implementation detail of StaticClass and export an interface StaticClass.IInstance to external clients:
public static class StaticClass {
public interface IInstance {
int Value { get; set; }
}
private class InstanceClass: IInstance {
public int oldValue;
public Value { get; set; }
}
// Static class becomes responsible for handing out `IInstance` objects
public static IInstance GetInstance() {
return new InstanceClass();
}
public static void Backup(IInstance i) {
if (i is InstanceClass ic) {
ic.oldValue = ic.Value;
}
else {
throw new InvallidOperationException("Can only Backup IInstance objects that were created by GetInstance");
}
}
public static void Restore(IInstance i) {
if (I is InstanceClass ic)
{
ic.Value = ic.oldValue;
}
else {
throw new InvallidOperationException("Can only Restore IInstance objects that were created by GetInstance");
}
}
This solution is similar to the one Luaan proposes. But instead of using an interface to export private data, it uses an interface to limit the publicly available data; to my opinion this is a cleaner design with less surprises.
It does change Value from a field to a property; so when you really need a field, this pattern does not work.
The static class in the example of OP makes it a bit awkward and having better solutions, but imagine this in a regular class, perhaps in a repository. Working on a repository, where observers should be notified when properties of items in the repository are set and not wanting the items to contain a reference to the repository or to the repositories observers, led me to searching for "method only accessible to container class?" which led me to this question.
I intend to solve it as follows:
public class Repo
{
public interface IItem
{
int Id { get; }
string MyProperty { get; }
}
private class Item
{
public int Id { get; }
public string MyProperty { get; private set; }
public bool TrySetMyProperty(string newValue)
{
if (!Equals(MyProperty, newValue) &&
IsPreconditionValid())
{
MyProperty = newValue;
return true;
}
else
{
return false;
}
IsPreconditionValid() => true;
}
}
public event EventHandler<EventArgs> OnChanged;
private readonly ConcurrentDictionary<int, Item> items = new ConcurrentDictionary<int, Item>();
public IItem GetOrCreateItemById(int id)
{
bool changed = false;
IItem result = items.GetOrAdd(int, CreateItem);
if (changed)
{
OnChanged?.Invoke(this, EventArgs.Empty);
}
return result;
IItem CreateItem(int key)
{
changed = true;
return new Item() { Id = key };
}
}
public bool TrySetItemMyProperty(int id, string newValue)
{
if (items.TryGet(id, out Item i))
{
if (i.TrySetMyProperty(newValue))
{
OnChanged?.Invoke(this, EventArgs.Empty);
return true;
}
}
return false;
}
}
I have abstract base class that contains some fields and some methods that act on these fields. For example:
public abstract class A
{
protected double _field;
public double SquaredField { get { return _field * _field; } }
... some other abstract methods
}
I want to impose that all children of A initialize _field in their constructors
public class B : A
{
public B(double field)
{
_field = Math.Sqrt(field);
}
... some other method implementations
}
What's the correct pattern to achieve this?
-- EDIT
What I ended up doing is:
public abstract class A
{
protected readonly double _field;
public A(double field)
{
_field = field;
}
public double SquaredField { get { return _field * _field; } }
... some other abstract methods
}
public class B : A
{
public B(double field) : base(field)
{
}
public static B CreateNew(double val)
{
return new B(Math.Sqrt(field));
}
... some other method implementations
}
Don't expose a field to the derived classes at all. Instead, create a protected abstract property:
public abstract class A
{
protected double Field { get; }
public double SquaredField { get { return Field * Field; } }
}
Or, if the field should always be constant for a particular instance, make it a constructor parameter and keep it private:
public abstract class A
{
private readonly double _field;
public double SquaredField { get { return _field * _field; } }
protected A(double field)
{
_field = field;
}
}
Don't let class A have a parameterless constructor:
public abstract class A
{
protected double _field;
public double SquaredField { get { return _field * _field; } }
// Require any fields that must be initialized in the base class's
// constructor. If there are a lot of such fields, consider encapsulating
// them all in their own class, e.g. AArgs.
protected A(double field)
{
_field = field;
}
}
public class B : A
{
// You must call a base class constructor as below, because class A
// no longer has a parameterless constructor to use by default.
public B(double field)
: base(field)
{
}
}
Addendum
If you can't do the initialization in the constructor, you could make the field into an abstract property:
public abstract class A
{
protected abstract double Field { get; }
public double SquaredField { get { return Field * Field; } }
}
Now, the derived class has to implement the property, so you'll have it ready for the dependent SquaredField property. I would change the name though, since they're not fields anymore.
That's likely a signal that group of fields is more tightly coupled than A itself, and so should be moved to a class, say, AParams.
Then in A you can declare an abstract protected AParams createParams() method.
You could use a separate abstract function to accomplish this. The subclasses would be forced to implement it.
public abstract class A
{
protected double _field;
protected A()
{
InitializeField();
}
protected abstract void InitializeField();
public double SquaredField { get { return _field * _field; } }
}
public class B : A
{
protected override void InitializeField()
{
// Initialize...
}
}
Suppose that we would like to separate out the read and write access in an interface pattern as below.
namespace accesspattern
{
namespace ReadOnly
{
public interface IA { double get_a(); }
}
namespace Writable
{
public interface IA : ReadOnly.IA { void set_a(double value); }
}
}
This is easy to implement:
namespace accesspattern
{
namespace ReadOnly
{
public class A : IA
{
protected double a;
public double get_a() { return a; }
}
}
namespace Writable
{
public class A : ReadOnly.A, IA
{
public void set_a(double value) { base.a = value; }
}
}
}
Suppose that we need another class which inherits from A and so we go ahead and define an interface for it:
namespace accesspattern
{
namespace ReadOnly
{
public interface IB : ReadOnly.IA { int get_b(); }
}
namespace Writable
{
public interface IB : ReadOnly.IB, Writable.IA { void set_b(int value); }
}
}
Implementing this is not so easy. One always feels that Writable.B should inherit from two base classes, Writable.A and ReadOnly.B, to avoid repeated code.
Is there a recommended Design Pattern to use? The aim is to be able to return "read access only" and "read write access" objects separately (decided at compile time) depending on requirements. It would be nice if the solution pattern makes it easy to add more layers of inheritance, classes C, D...
I know that the issue of Multiple Inheritance crops up here and that it has been discussed at length elsewhere in many, many, places. But my question is not so much "How to implement the interfaces which are defined inside the namespace accesspattern without using multiple inheritance" (although I would like to learn the best way to do that) but rather, how can we define the ReadOnly/Writable versions of a class separately and also support inheritance without it getting very, very, messy?
For what it is worth here is one (messy) solution [see below for much a better implementation]:
namespace accesspattern
{
namespace ReadOnly
{
public class A : IA
{
protected double a;
public double get_a() { return a; }
}
public class B : IB
{
protected int b;
public int get_b() { return b; }
}
}
namespace Writable
{
public class A : ReadOnly.A, IA
{
public void set_a(double value) { base.a = value; }
}
public class B : ReadOnly.B, IB
{
private IA aObj;
public double get_a() { return aObj.get_a(); }
public void set_a(double value) { aObj.set_a(value); }
public void set_b(int value) { base.b = value; }
public B() { aObj = new A(); }
}
}
}
}
Update: I think that this (below) is what Eugene is talking about. This implementation pattern is pretty good, I think. By only passing around "writeProtected" views of classes one can implement algorithms which require that the state of the class will not change and only use "writeEnabled" views where it is meant that the function will/could cause a change in state avoiding.
namespace access
{
// usual usage is at least readable
public interface IA { double get_a(); }
public interface IB : IA { int get_b(); }
// special usage is writable as well
namespace writable
{
public interface IA : access.IA { void set_a(double value); }
public interface IB : access.IB, IA { void set_b(int value);}
}
// Implement the whole of A in one place
public class A : writable.IA
{
private double a;
public double get_a() { return a; }
public void set_a(double value) { a = value; }
public A() { }
//support write-protection
public static IA writeProtected() { return new A(); }
public static writable.IA writable() { return new A(); }
}
// implement the whole of B in one place and now no issue with using A as a base class
public class B : A, writable.IB
{
private int b;
public double get_b() { return b; }
public void set_b(int value) { b = value; }
public B() : base() { }
// support write protection
public static IB writeProtected() { return new B(); }
public static writable.IB writable() { return new B(); }
}
public static class Test
{
static void doSomething(IA a)
{
// a is read-only
}
static void alterState(writable.IB b)
{
// b is writable
}
static void example()
{
// Write protected
IA a = access.A.writeProtected();
IB b = access.B.writeProtected();
// write enabled
writable.IA A = access.A.writable();
writable.IB B = access.B.writable();
Console.WriteLine(a.get_a());
B.set_b(68);
doSomething(A); // passed as writeprotected
alterState(B); // passed as writable
}
}
}
I know this thread is one year old, but I'm wondering if it would make sense to have something like this:
interface ReadOnlyA
{
object A { get; }
}
interface WriteableA : ReadOnlyA
{
new object A {get; set;}
}
You can provide the read/write access at Service level and not at Entity level. In that case you can code generate a wrapper around services that handles the read/write access.
Patterns used: Decorator, Dependency Injection
When you're using a factory pattern, how do you inject dependencies into constructors at runtime?
I'm building Foos with different formats - boolean, array, freetext, matrix, etc. That format list will grow as we find different uses for Foo. Here's my basic core domain:
public interface IFoo
{
FooFormat Format { get; }
}
public class Foo : IFoo
{
private FooFormat _format;
internal Foo(FooFormat format)
{
_format = format;
}
public FooFormat Format { get { return _format; } }
}
public abstract class FooFormat
{
}
public class DefaultFooFormat : FooFormat
{
}
public class BooleanFooFormat : FooFormat
{
public IList<bool> Values { get; set; }
}
public class ArrayFooFormat : FooFormat
{
private IList<string> _values;
public ArrayFooFormat(IList<string> values)
{
_values = values;
}
public IList<string> Values { get { return _values; } }
}
IFoo is decorated for the consumer context:
public abstract class FooDecorator : IFoo
{
private IFoo _foo;
protected FooDecorator(IFoo foo)
{
_foo = foo;
}
public FooFormat Format
{
get { return _foo.Format; }
}
protected IFoo foo
{
get { return _foo; }
}
}
I don't want my consumer to instantiate a Foo directly, so I force them to use a factory:
public abstract class FooFactory
{
protected IFoo Build<T>()
{
FooFormat format = GetFormat<T>();
return new Foo(format);
}
private FooFormat GetFormat<T>()
{
if (typeof(T) == typeof(ArrayFooFormat)) return new ArrayFooFormat(new List<string>());
if (typeof(T) == typeof(BooleanFooFormat)) return new BooleanFooFormat();
return new DefaultFooFormat();
}
}
And even then, they need to derive a factory from my abstract factory for their particular context.
I'm specifically building foos in an html context, like so:
public class HtmlFoo : FooDecorator
{
public HtmlFoo(IFoo foo) : base(foo) { }
public string ToHtml()
{
return "<div>" + this.Format.ToString() + "</div>";
}
}
public class HtmlFooFactory : FooFactory
{
public IFoo BuildFoo<T>()
{
IFoo foo = Build<T>();
return new HtmlFoo(foo);
}
}
public class HtmlFooConsumer
{
public void DoSomeFoo()
{
var factory = new HtmlFooFactory();
var htmlBooleanFoo = factory.BuildFoo<BooleanFooFormat>();
var htmlArrayFoo = factory.BuildFoo<ArrayFooFormat>();
}
}
My problem is in my abstract FooFactory: I'm always injecting an empty value list into my ArrayFooFormat. I want to be able to pass in a value list from the consumer. For other FooFormats, I want to pass in the right constructor arguments from the consumer. But I want to keep the public API dead simple - I don't want a bunch of overloads on BuildFoo().
So how do I pass a custom value list into the factory.BuildFoo<T>() call from inside HtmlFooConsumer.DoSomeFoo()? Any ideas, stackoverflow gurus?
Maybe you can do something along these lines where your abstract FooFormat becomes IFooFormat and a generic FooFormat provides an Init method that gets passed the parameter.
Then a single overload of Build lets you pass in the parameter.
public interface IFooFormat
{
}
public class FooFormat<TValue> : IFooFormat
{
private TValue _value;
public void Init(TValue value)
{
_value = value;
}
public TValue Value
{
get { return _value; }
}
}
public class ArrayFooFormat : FooFormat<IList<string>> { }
public class BooleanFooFormat : FooFormat<bool> { }
public class DefaultFooFormat : IFooFormat { }
public interface IFoo { }
public class Foo : IFoo
{
private IFooFormat _format;
internal Foo(IFooFormat format)
{
_format = format;
}
public IFooFormat Format { get { return _format; } }
}
public class FooFactory
{
protected IFoo Build<TFormat, TArg>(TArg arg) where TFormat : FooFormat<TArg>, new()
{
TFormat format = new TFormat();
format.Init(arg);
return new Foo(format);
}
protected IFoo Build<TFormat>() where TFormat : IFooFormat, new()
{
return new Foo(new TFormat());
}
}
A factory is basically the object oriented version of a static variable. I'd avoid using one alltogether. Instead of forcing clients to use a factory, perhaps you can simply inject objects into their constructors, sidestepping the need for a factory.