For a class that can be saved in a persistence medium i am creating Interface called IPersistable which is designed to provide a persistenceId.
public interface IPersistable
{
private readonly string persistenceId;
}
Certainly i can't do the above since Interfaces do not allow fields. If it did i would have done below to accomplish it
Public Class Customer
{
private readonly string persistenceId;
Public string UserId
{
get{return persistenceId};
}
Public Customer(string customerId)
{
persistenceId = customerId;
}
}
I already am inheriting a class hence not possible to do multiple inheritance. I could use composition but Interface seems right thing here. Show me a neat hack to do the above instead of adding a property to each class that needs to be persisted.
Question
If possible, can a class that Interfaces with IPersistable change the name of the property( if persistenceId is a property), to something meaningful ?
An interface won't help you if you want to be able to persist existing types such as int or string. Maybe instead of an interface you could use a wrapping class? Something like:
class Persistable<T>
{
public Persistable<T>(string PersistanceId, T Data)
public readonly string PersistanceId;
public readonly T Data;
}
What's wrong with?
public interface IPersistable
{
String PersistenceId { get; }
}
Public Class Customer : IPersistable
{
public string PersistenceId { get; private set; }
public string UserId {
get { return PersistenceId; }
}
.
.
.
}
Try something like this:
public interface IPersistable<TType>
{
TType PersistenceId { get; }
}
public abstract PersistableEntity<TType> : IPersistable<TType>
{
private TType persistenceId;
public TType PersistenceId
{
get { return persistenceId; }
}
public PersistableEntity(TType persistenceId)
{
this.persistenceId = persistenceId;
}
}
public class Customer : PersistableEntity<string>
{
public Customer(string persistenceId)
: base(persistenceId)
{
}
}
Related
I've been reading a lot about composition and trying to figure how I can refactor my inheritance tree using composition. Currently my class looks like this:
public abstract class BaseClass
{
public abstract string displayText { get; }
public abstract List<Parameter> parameters { get; }
public abstract void FireEvent();
}
public abstract class SubClass<T> : BaseClass
{
private string _displayText;
public override string displayText { get { return _displayText; } }
private List<Parameter> _parameters;
public override List<Parameter> parameters { get { return _parameters; } }
private T _value; // ADDED TO SUBCLASS
public abstract Event<T> Evt { get; } // ADDED TO SUBCLASS
public override void FireEvent()
{
Evt.Raise(_value);
}
}
public class IntClass : SubClass<int>{}
public class StringClass : SubClass<string>{} // more subclasses like this
From my understanding, there is both inheritance and composition going on here.
SubClass Has-A: (Composition)
List of Parameters
Field for Event
Behaviour of Event<T> which is called within it's own FireEvent method
SubClass Is-A: BaseClass (Inheritance)
IntClass/StringClass Is-A: SubClass & BaseClass
The reason for creating BaseClass is because I need polymorphic lists. This way I can create a List<BaseClass> and call FireEvent() on each element in the list and access the displayText and List<Parameter> in a loop.
In the future I will need a sub class which doesn't have an Event and a subclass which will accept a parameter in FireEvent(). Other variants might crop up.
How would I replace my current structure entirely with a composition based approach? Is it even doable?
In this example, you have 3 behaviors. Int uses 3, String uses only 2. If you put the code like this, when you change AnotherServiceB, you don't need to be worry about it break String (since String doesn't have that service)
public class FireEventService<T>
{
private T _value; // ADDED TO SUBCLASS
public abstract Event<T> Evt { get; } // ADDED TO SUBCLASS
public override void FireEvent()
{
Evt.Raise(_value);
}
}
public class AnotherService
{
}
public class AnotherServiceB
{
}
public abstract class SubClass<T> : BaseClass
{
private readonly FireEventService<T> _fireEventService;
private readonly AnotherService _anotherService;
private string _displayText;
public override string displayText { get { return _displayText; } }
private List<Parameter> _parameters;
public override List<Parameter> parameters { get { return _parameters; } }
public SubClass(FireEventService<T> fireEventService, AnotherService anotherService)
{
// All those services should use with interface and Dependency Injection
_fireEventService = fireEventService;
_anotherService = anotherService;
}
public void FireEvent() => _fireEventService.FireEvent();
}
public class IntClass : SubClass<int>
{
private readonly AnotherServiceB _anotherServiceB;
public IntClass(FireEventService<int> fireEventService, AnotherService anotherService, AnotherServiceB anotherServiceB)
: base(fireEventService, anotherService)
{ }
public void DoSomethingUsingServiceB()
{
//_anotherServiceB.DoSomething();
}
}
public class StringClass : SubClass<string>
{
public StringClass(FireEventService<string> fireEventService, AnotherService anotherService)
: base(fireEventService, anotherService)
{ }
}
I need to create a dll file which contains all the interfaces of the classes but doesn't contain any class.
Because I use these interfaces for a lot of classes it's must be like that:
public interface IClassA
{
string Word { get; }
}
public interface ITest<TClassA> where TClassA : IClassA
{
TClassA A { get; }
}
Example of two classes that implements these interfaces the way I want:
public class ClassA : IClassA
{
public string Word
{
get;
private set;
}
public string Sentence
{
get;
private set;
}
public ClassA(string word, string sentence)
{
this.Word = word;
this.Sentence = sentence;
}
}
public class Test : ITest<ClassA>
{
public ClassA A
{
get;
private set;
}
public Test(ClassA a)
{
this.A = a;
}
}
And I want to do something like that in the main program:
public static void Main(string[] args)
{
ClassA a = new ClassA("hey", "hey world!");
Test t = new Test(a);
Print((ITest<IClassA>)t);
}
public static void Print(ITest<IClassA> t)
{
Console.WriteLine(t.A.Word);
}
But this casting: (ITest<IClassA>)t makes a run time error.
How can I solve it?
thanks!
You should declare Test as
public class Test : ITest<IClassA>
instead of ITest<ClassA>.
Or declare ITest<TClassA> to be covariant on TClassA:
public interface ITest<out TClassA> where TClassA : IClassA
The Test-class implements the concrete ClassA (public class Test : ITest<ClassA>).
So you're trying to cast an ITest<ClassA> to ITest<IClassA> which obviously fails.
If you let the Test-class implement IClassA, the cast works:
public class Test : ITest<IClassA>
{
public IClassA A
{
get; private set;
}
public Test(IClassA a)
{
this.A = a;
}
}
The best practices are to program against the interface rather than the concrete class. I want to keep container of class that implements interface IPet. Does it correct? List<IPet> petList = new List<IPet>(); Or it's better to create an abstract class?
public interface IPet
{
string Name { get; set; }
void Introduce();
}
public class Parrot : IPet
{
public string Name { get; set; }
public Parrot(string name)
{
Name = name;
}
public void Introduce()
{
Console.WriteLine($"My name is {Name}. I am a parrot");
}
}
public class Cat : IPet
{
public string Name { get; set; }
public Cat(string name)
{
Name = name;
}
public void Introduce()
{
Console.WriteLine($"My name is {Name}. I am a cat");
}
}
PetShop petShop = new PetShop();
petShop.Add(new Cat("Garfield"));
petShop.Add(new Parrot("Kesha"));
Using interface in generics is the good choice!
Using abstract class force you to place any type in single chain of inheritance that can cause a problem with application evolution.
Besides, if you have a repeating behavoir you can create abstract class wich implements required interface, so you'll get advantages of both ways.
You can easily create an abstract class and put all repeating logic into it. Your classes look the same, only the Introduce() method is different, but you can use this.GetType().Name.ToLower() instead of "cat" and "parrot".
So, you can have the following:
public abstract class Pet : IPet
{
public string Name { get; set; }
protected Pet(string name)
{
Name = name;
}
public void Introduce()
{
Console.WriteLine($"My name is {Name}. I am a {this.GetType().Name.ToLower()}");
}
}
public class Cat : Pet
{
public Cat(string name)
: base(name)
{
}
}
I am attempting to do something similar to:
public interface IView<T> : T where T : class
{
T SomeParam {get;}
}
So that i can later do
public class SomeView : IView<ISomeView>
{
}
Is it possible to specify inheritance using generics in this way or do i have to go the long way round and explicitly specify both interfaces when defining the class and do:
public interface IView<T>
{
T SomeParam {get;}
}
public class SomeView : IView<ISomeView>, ISomeView
{
}
This isn't possible, but your goal may be achievable with conversion operators. It seems that what you're trying to do is make it possible to pass an IView<T> as the T object which it contains. You could write a base class like this:
public abstract class ViewBase<T> {
public abstract T SomeParam { get; }
public static implicit operator T(ViewBase<T> view) {
return view.SomeParam;
}
}
Then, if you define a class like:
public class SomeView : ViewBase<ISomeView> { }
It can be accepted anywhere an ISomeView is expected:
ISomeView view = new SomeView();
Short answer: It is not possible. See this post
An Interface can't derive from a class. However nothing prevent you from doing this:
public interface ISomeView
{
}
public interface IView<out T> where T:class
{
T SomeParam { get; }
}
public class SomeView:IView<ISomeView>
{
public ISomeView SomeParam { get; set; }
}
Edit:
If you don't want to implement the T SomeParam { get; } each time you need to have an implementation, Does this would work?
public interface ISomeView
{
}
public abstract class BaseView<T> where T : class
{
public T SomeParam { get; set; }
}
public class SomeView : BaseView<ISomeView>{
}
In both case this would work:
public class main
{
public class OneOfThoseView : ISomeView
{
}
public main()
{
OneOfThoseView oneOfThose = new OneOfThoseView();
SomeView x = new SomeView();
x.SomeParam = oneOfThose;
}
}
Edit 2:
Not exactly what you want to do but this would force your SomeView class to return a BaseView<SomeView> class
public interface ISomeView
{
}
public abstract class BaseView<T> where T : BaseView<T>
{
public T SomeParam { get; set; }
}
public class SomeView : BaseView<SomeView>
{
}
Now only this would work.
public main()
{
SomeView y= new SomeView ();
SomeView x = new SomeView();
x.SomeParam = y;
}
I have the following classes and interfaces:
public interface IThing
{
string Name { get; }
}
public class Thing : IThing
{
public string Name { get; set; }
}
public abstract class ThingConsumer<T> where T : IThing
{
public string Name { get; set; }
}
Now, I have a factory that will return objects derived from ThingConsumer like:
public class MyThingConsumer : ThingConsumer<Thing>
{
}
My factory currently looks like this:
public static class ThingConsumerFactory<T> where T : IThing
{
public static ThingConsumer<T> GetThingConsumer(){
if (typeof(T) == typeof(Thing))
{
return new MyThingConsumer();
}
else
{
return null;
}
}
}
I'm getting tripped up with this error: Error 1 Cannot implicitly convert type 'ConsoleApplication1.MyThingConsumer' to 'ConsoleApplication1.ThingConsumer<T>'
Anyone know how to accomplish what I'm attempting here?
Thanks!
Chris
If you make ThingConsumer<T> an interface rather than an abstract class, then your code will work as is.
public interface IThingConsumer<T> where T : IThing
{
string Name { get; set; }
}
Edit
One more change needed. In ThingConsumerFactory, cast back to the return type IThingConsumer<T>:
return (IThingConsumer<T>)new MyThingConsumer();
The compiler is stumbling over the conversion from MyThingConsumer to ThingConsumer<T> even though T:IThing and MyThingConsumer:Thingconsumer<Thing> and Thing:IThing. Which is quite a few hoops for it to jump through!
The code works if you use return new MyThingConsumer() as ThingConsumer<T>; instead of a direct cast. You know the result will never be null, and the compiler is happy because it is guaranteed a return value of the right type at runtime.
Edit:
Here is the full code I used for testing (in Snippy):
public interface IThing
{
string Name { get; }
}
public class Thing : IThing
{
public string Name { get; set; }
}
public abstract class ThingConsumer<T> where T : IThing
{
public string Name { get; set; }
}
public class MyThingConsumer : ThingConsumer<Thing>
{
}
public static class ThingConsumerFactory<T> where T : IThing
{
public static ThingConsumer<T> GetThingConsumer()
{
if (typeof(T) == typeof(Thing))
{
return new MyThingConsumer() as ThingConsumer<T>;
}
else
{
return null;
}
}
}
...
var thing = ThingConsumerFactory<Thing>.GetThingConsumer();
Console.WriteLine(thing);
You need to define your class like this I believe:
public class MyThingConsumer<Thing> : ThingConsumer
The reason is that ThingConsumer is already typed in its definition with this: where T : IThing
Now, you can make the call return new MyThingConsumer<T>();.
This should in turn match the expected return type of ThingConsumer<T>
EDIT
Sorry for the confusion, here is what should work:
public class MyThingConsumer<T> : ThingConsumer<T> where T : IThing
and
return new MyThingConsumer<T>();