public interface IMyClassClient
{
MyClass<T> Default();
//T cannot be found, error
}
public class MyClass<T>
{
private IMyClassClient owner;
private MyClass<T> test;
public MyClass<T> Test
{
get { return _test;}
set
{
if(value ==owner.Default())
{
//how to form this call?^^^^^
MessageBox.Show("Well that's true");
}
}
}
}
The objective is that a class implementing IMyClassClient will handle figuring out a return value for IMyClassClient.Default()
What am I missing here?
EDIT:
After some thought, the following is a better wording of what I need to accomplish:
public interface IMyInterface
{
//see Instance member in SomeClass, down below? How to declare it here?
}
public class SomeClass:IMyInterface
{
public MyClass<int> Instance()
{
return new myClass<int>(); //for brevity
}
}
You should use generic in interface too, if you don't do it, you couldn't write MyClass<T> Default() , you don'T have any T there.
public interface IMyClassClient<T>
{
MyClass<T> Default();
}
public class MyClass<T>
{
private IMyClassClient<T> owner;
private MyClass<T> test;
public MyClass<T> Test
{
get { return test; }
set
{
if (value == owner.Default())
{
MessageBox.Show("Well that's true");
}
}
}
}
EDIT: Sure, you could declare geeric function in non generic interface
public interface IMyInterface
{
MyClass<T> Instance<T>();
}
public class SomeClass : IMyInterface
{
public MyClass<int> Instance()
{
return new myClass<int>();
}
}
Related
Say I have the following
public interface IInterval<T>
{
T Start { get; }
T Stop { get; }
}
public class DateTimeInterval : IInterval<DateTime>
{
private DateTime _start;
private DateTime _stop;
public DateTimeInterval(DateTime start, DateTime stop)
{
_start = start; _stop = stop;
}
public DateTime Start
{
get { return _start; }
}
public DateTime Stop
{
get { return _stop; }
}
}
public class SortedIntervalList<T>
where T : IInterval<T>, IComparable<T>
{
}
If I were to now try to instantiate the container
var test = new SortedIntervalList<DateTimeInterval>();
I get a compilation error
The type 'Test' cannot be used as type parameter 'T' in the generic
type or method TestContainer<T>. There is no implicit reference
conversion from 'Test' to ITest<Test>.
Why is this?
Note on edit history
For clarity, classes for the original question are included below
public interface ITest<T>
{
int TestMethod();
}
public class Test : ITest<bool>
{
public int TestMethod()
{
throw new NotImplementedException();
}
}
public class TestContainer<T>
where T : ITest<T>
{
}
where T : ITest<T>
Your class inherits ITest<bool>, which is not ITest<T> for your T (Test).
As the error is trying to tell you, that does not meet your generic constraint, so you can't do that.
Because you expect your T in TestContainer<T> to be ITest<T>. that doesn't make sense. I think you meant :
public class TestContainer<C, T>
where C : ITest<T>
{
}
For your updated code in your question:
public class SortedIntervalList<C, T>
where C : IInterval<T>, IComparable<T>
{ }
With:
test = new SortedIntervalList<DateTimeInterval, DateTime>();
I want to have a base class:
public class Base
{
public static T Instance
{
get
{
// do something to return new instance of inherit class from itself
}
}
}
Class1:
public class Class1 : Base
{
// method and properties here
public string Func1()
{
return 'class1';
}
}
Class2:
public class Class2 : Base
{
// method and properties here
public string Func1()
{
return 'class2';
}
}
I want it so that we can use Class1 or Class2 like this
public class Main
{
var a = Base<Class1>.Instance.Func1(); // return 'class1'
var b = Base<Class2>.Instance.Func1(); // return 'class2'
}
Please help me to do this.
This is not called dynamic but polymorphic. In this case achieved with generics. Your only remaining problem is calling the constructor, which becomes possible when you put a Type-constraint on <T>.
public class Base<T> where T : new()
{
public static T Instance
{
get
{
// do something to return new instance of inherit class from itself
return new T();
}
}
}
and then:
public class Class1 : Base<Class1> { ... }
public class Class2 : Base<Class2> { ... }
But note that a simpler solution could be achieved with virtual+override methods or with an interface.
Alternative suggestion with some tighter type constraints:
namespace My.Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Base<Class1>.Instance.Func1());
Console.WriteLine(Base<Class2>.Instance.Func1());
}
}
public abstract class Base
{
public abstract string Func1();
}
public sealed class Base<T> where T : Base, new()
{
public static T Instance
{
get { return new T(); }
}
}
public class Class1 : Base
{
public override string Func1() { return "class 1"; }
}
public class Class2 : Base
{
public override string Func1() { return "class 2"; }
}
}
The following code is a simple example of a program I am writing.
public class Y
{ }
public class X : Y
{ }
public class W : Y
{ }
public interface IAaa<T>
where T : Y
{
void Execute(T ppp);
}
public abstract class Aaa<T> : IAaa<T>
where T : Y
{
public abstract void Execute(T ppp);
}
public class Bbb : Aaa<X>
{
public override void Execute(X ppp)
{ }
}
public class Ccc : Aaa<W>
{
public override void Execute(W ppp)
{ }
}
public class Factory
{
public static IAaa<Y> Get(bool b)
{
if(b)
return new Bbb();
else
return new Ccc();
}
}
class Program
{
static void Main(string[] args)
{
IAaa<Y> aa;
aa = Factory.Get(true);
}
}
when I compile it I get the following errors
error CS0266: Cannot implicitly convert type 'ConsoleApplication3.Bbb'
to 'ConsoleApplication3.IAaa'. An explicit
conversion exists (are you missing a cast?)
error CS0266: Cannot implicitly convert type 'ConsoleApplication3.Ccc'
to 'ConsoleApplication3.IAaa'. An explicit
conversion exists (are you missing a cast?)
Is there any way to make it work?
You can't use the interface in the way you're trying to. Lookup covariance/contravariance, you're trying to do the opposite of what's possible (you have in interface that could be <in T> but you're trying to use it like <out T>).
Take class Bbb for instance - it has an Execute(X) method. What would happen if you tried to pass a Y (which may or may not be an X) to that? The compiler doesn't allow it, because you never defined in the code what should happen in that case.
You can do what you want by creating and implementing another interface, IAaa. E.g.
public interface IAaa
{
void Execute(Y ppp);
}
Perhaps implemented like this, so that if you try to call it with an invalid type, a cast exception is thrown:
void Main()
{
IAaa aa;
aa = Factory.Get(true);
}
public class Y
{ }
public class X : Y
{ }
public class W : Y
{ }
public interface IAaa<T> : IAaa
where T : Y
{
void Execute(T ppp);
}
public interface IAaa
{
void Execute(Y ppp);
}
public abstract class Aaa<T> : IAaa<T>
where T : Y
{
public abstract void Execute(T ppp);
void IAaa.Execute(Y ppp)
{
this.Execute(ppp);
}
protected abstract void Execute(Y ppp);
}
public class Bbb : Aaa<X>
{
public override void Execute(X ppp)
{ }
protected override void Execute(Y ppp)
{
this.Execute((X)ppp);
}
}
public class Ccc : Aaa<W>
{
public override void Execute(W ppp)
{ }
protected override void Execute(Y ppp)
{
this.Execute((W)ppp);
}
}
public class Factory
{
public static IAaa Get(bool b)
{
if(b)
return new Bbb();
else
return new Ccc();
}
}
As the error says, you are missing a cast. I believe this is what you need:
public static IAaa<Y> Get(bool b)
{
if(b)
return (IAaa<Y>)(new Bbb());
else
return (IAaa<Y>)(new Ccc());
}
You could cast to (IAaa<Y>) and your code would compile.
However it will not work and will fail at run-time.
Why?
Your classes Bbb and Ccc are specialized classes and the Execute method cannot process ALL types of Aaa. You have to tell C# / the compiler.
UPDATE:
By having a generic Factory you can get specialized instances of IAaa and your code should work.
In your Program you already know the type as you pass TRUE or FALSE to the Factory, so you need to explicitly tell C# the type of the Interface implementation you want to use.
(refactor the Factory class accordingly, I'm just sending what should compile)
public class Y
{ }
public class X : Y
{ }
public class W : Y
{ }
public interface IAaa<T>
where T : Y
{
void Execute(T ppp);
}
public abstract class Aaa<T> : IAaa<T>
where T : Y
{
public abstract void Execute(T ppp);
}
public class Bbb : Aaa<X>
{
public override void Execute(X ppp)
{ }
}
public class Ccc : Aaa<W>
{
public override void Execute(W ppp)
{ }
}
public class Factory<T> where T : Y
{
public static IAaa<T> Get(bool b)
{
if(b)
return (IAaa<T>)new Bbb();
else
return (IAaa<T>)new Ccc();
}
}
class Program
{
static void Main(string[] args)
{
IAaa<X> aa;
aa = Factory<X>.Get(true);
}
}
UPDATE 2
Just an example of how you could refactor the Factory class:
public class Factory<T, U>
where T : Y
where U : Aaa<T>, new()
{
public static IAaa<T> Get()
{
return (IAaa<T>)new U();
}
}
class Program
{
static void Main(string[] args)
{
IAaa<X> aa;
aa = Factory<X, Bbb>.Get();
}
}
I have three classes that will each return a slightly different result.
// interfact to a king
public interface IKing{
public Result Get();
}
// main abstract class
public abstract class King:IKing{
public abstract Result Get();
}
// main abstract result
public abstract class Result{
public int Type {get;set;}
}
// KingA result
public class ResultA:Result{
...
}
// KingB result
public class ResultB:Result{
...
}
// concrete implementations
public class KingA:King{
public override ResultA Get(){
return new ResultA;
}
}
public class KingB:King{
public override ResultB Get(){
return new ResultB
}
}
This will not work since the King overriden method of Get is expecting the Result class and will not accept its children ResultA and ResultB.
Is there a better approach I can take?
The usual approach is to use generics.
public interface IKing<T> where T:Result{
T Get();
}
public class King<T> : IKing<T>
public abstract T Get();
}
public class KingA : King<ResultB> {
public override ResultA Get(){
return new ResultA();
}
}
public class KingB : King<ResultB> {
public override ResultB Get(){
return new ResultB();
}
}
Edit: fixed syntax.
It will help if you use code that compiles. Your 'concrete implementations' are bogus, it looks like you mixed the concepts of class and method. There is otherwise no design problem here. For example:
public class KingA : King {
public override Result Get() {
return new ResultA();
}
}
I think there's some syntax confusion here -- if I captured your intent correctly, this works fine:
// interface to a king
public interface IKing
{
Result Get();
}
// main abstract class
public abstract class King : IKing
{
public abstract Result Get();
}
// main abstract result
public abstract class Result
{
private int _Type;
public int Type { get { return _Type; } set { _Type = value; } }
}
// KingA result
public class ResultA : Result
{
}
// KingB result
public class ResultB : Result
{
}
// concrete implementations
public class KingA : King
{
public override Result Get()
{
return new ResultA();
}
}
public class KingB : King
{
public override Result Get()
{
return new ResultB();
}
}
class Program
{
static void Main(string[] args)
{
IKing ka = new KingA();
IKing kb = new KingB();
Result ra = ka.Get();
Result rb = kb.Get();
if (ra is ResultA)
{
Console.WriteLine("A ok!");
}
if (rb is ResultB)
{
Console.WriteLine("B ok!");
}
}
}
(edited for formatting)
You should be able to explicitly cast ResultA and ResultB as Result in the implementations of Get (I'm assuming that's what the "concrete implementations" are intended to be).
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.