I have following code:
public abstract class Operand<T>
{
public T Value { get; protected set; }
public bool IsEmpty { get; protected set; }
public override string ToString()
{
return IsEmpty ? Value.ToString() : string.Empty;
}
}
public class DoubleOperand : Operand<Double> {}
public interface IOperandFactory<T>
{
Operand<T> CreateEmptyOperand();
Operand<T> CreateOperand(T value);
}
public class DoubleFactory: IOperandFactory<double>
{
public Operand<Double> CreateEmptyOperand()
{
//implementation
}
public Operand<Double> CreateOperand(double value)
{
//implementation
}
}
I simlified code to just show the structure.
Now I need associationDictionary that will return IOperandFactory for required Type:
Something like this:
var factoryDict =
new Dictionary<Type, IOperandFactory<>>() { { typeof(double), new DoubleFactory() } };
Could you help me to achieve it if it is possible?
To do that, you would need to have a non-generic interface (typically in addition to the generic interface), i.e. a non-generic Operand, with Operand<T> : Operand (could also be an interface), and a non-generic IOperandFactory with IOperandFactory<T> : IOperandFactory. The only other option is to store a Dictionary<Type, object>, and have the caller cast as necessary.
Here's the non-generic approach:
using System.Collections.Generic;
using System;
public interface IOperand
{
object Value { get; }
bool IsEmpty { get; }
}
public abstract class Operand<T> : IOperand
{
public T Value { get; protected set; }
object IOperand.Value { get { return Value; } }
public bool IsEmpty { get; protected set; }
public override string ToString()
{
return IsEmpty ? Value.ToString() : string.Empty;
}
}
public class DoubleOperand : Operand<double> { }
public interface IOperandFactory
{
IOperand CreateEmptyOperand();
IOperand CreateOperand(object value);
}
public interface IOperandFactory<T> : IOperandFactory
{
new Operand<T> CreateEmptyOperand();
Operand<T> CreateOperand(T value);
}
public class DoubleFactory : IOperandFactory<double>
{
public Operand<double> CreateEmptyOperand()
{
throw new NotImplementedException();
}
IOperand IOperandFactory.CreateEmptyOperand() {
return CreateEmptyOperand();
}
IOperand IOperandFactory.CreateOperand(object value) {
return CreateOperand((double)value);
}
public Operand<double> CreateOperand(double value)
{
throw new NotImplementedException();
}
}
static class Program
{
static void Main()
{
var factoryDict = new Dictionary<Type, IOperandFactory> {
{typeof (double), new DoubleFactory()}
};
}
}
If I understand correctly, you are trying to store a collection of generic types, where the generic type parameters may vary. If this is the case, it is not directly possible, as the following example illustrates:
// You have lists of different types:
List<double> doubleCollection = new List<double>();
List<string> stringCollection = new List<string>();
// Now to store generically:
var collection = new List<List< /* ... Which type parameter to use? ... */ >>();
What should be apparent here, is that it is not possible to deduce which type parameter to use. Instead (with regards to your example), you may want something like this instead:
public interface IOperand
{
}
public interface IOperand<T>
{
}
public interface IOperandFactory
{
IOperand CreateEmptyOperand();
IOperand CreateOperand(object value);
}
public interface IOperandFactory<T> : IOperandFactory
{
new IOperand<T> CreateEmptyOperand();
IOperand<T> CreateOperand(T value);
}
public class DoubleFactory : IOperandFactory<double>
{
public IOperand<double> CreateEmptyOperand()
{
throw new NotImplementedException();
}
public IOperand<double> CreateOperand(double value)
{
throw new NotImplementedException();
}
IOperand IOperandFactory.CreateEmptyOperand()
{
throw new NotImplementedException();
}
public IOperand CreateOperand(object value)
{
throw new NotImplementedException();
}
}
public class SomeContainer
{
public SomeContainer()
{
var factoryDict = new Dictionary<Type, IOperandFactory>()
{
{ typeof(double), (IOperandFactory)new DoubleFactory() }
};
}
}
This may not be the most elegant of solutions, but it would allow you to store different generic types in the same collection. An issue with this, however, is that the caller accessing such a collection would need to know what type to cast to. For example:
// ... Inside SomeContainer ...
public IOperandFactory<T> GetFactory<T>()
{
return (IOperandFactory<T>)factoryDict[typeof(T)];
}
So with this, you can get the DoubleFactory using:
IOperandFactory<double> doubleFactory = mSomeContainerInstance.GetFactory<double>();
IOperand<double> emptyOperand = doubleFactory.CreateEmptyOperand();
IOperand<double> filledOperand = doubleFactory.CreateOperand(1.0d);
Related
How force to use class that implement generic interface in class?
Is something like this possible?
public interface IGeneric<T>
{
T Value {get;}
}
//public class MyList<IGeneric<T>> {}//not allowed
Something like this:
void Main()
{
MyList<string> myList = new MyList<string>(new Generic());
}
public interface IGeneric<T>
{
T Value { get; }
}
public class MyList<T>
{
private IGeneric<T> _generic;
public MyList(IGeneric<T> generic)
{
_generic = generic;
}
}
public class Generic : IGeneric<string>
{
public string Value => throw new NotImplementedException();
}
Or like this:
void Main()
{
MyList<Generic, string> myList = new MyList<Generic, string>();
//Or MyList<IGeneric<string>, string> myList = new MyList<IGeneric<string>, string>();
}
public interface IGeneric<T>
{
T Value { get; }
}
public class MyList<G, T> where G : IGeneric<T>
{
}
public class Generic : IGeneric<string>
{
public string Value => throw new NotImplementedException();
}
I have a generic list of objects, but the types within the list are all different types. However, when iterating over the list of objects, and then calling a generic function, the type of T defined in the generic is of type Object. How can I get the pattern matching to work so that type of T matches the concrete type of the object being validated? For example, In the contrived example below, when calling Validate on the ValidationService, the line
if(validator is IValidator<T> typedValidator)
always fails because type of T is object, and the physical implementation would be IValidator<Widget> or IValidator<Entity>. How should I change the DemonstrateProblem() method so that the call to validationService.Validate uses the concrete type for the function and not the type of the type as defined in the the List<object>? To make it slightly more complex, my actual code is also asynchronous, so I actually need a return value of Task<IValidationResult<T>>
namespace Contrived
{
public interface IValidator { }
public interface IValidationResult<T> { }
public interface IValidator<T> : IValidator
{
IValidationResult<T> Validate(T entity);
}
public class ValidationResult<T> : IValidationResult<T>
{
public bool IsValid { get; set; }
}
public class Entity
{
public int Id { get; set; }
public string SomeProperty { get; set; }
}
public class EntityValidator : Contrived.IValidator<Entity>
{
public IValidationResult<Entity> Validate(Entity entity)
{
return new ValidationResult<Entity>() { IsValid = true };
}
}
public class Widget
{
public Guid UniqueIdentifier { get; set; }
}
public class WidgetValidator : IValidator<Widget>
{
public IValidationResult<Widget> Validate(Widget entity)
{
return new ValidationResult<Widget>() { IsValid = true };
}
}
public class ValidationService
{
private readonly Dictionary<Type, IValidator> validators;
public ValidationService(Dictionary<Type, IValidator> validators)
{
this.validators = validators;
}
public IValidationResult<T> Validate<T>(T validatingObject)
{
var validator = validators[validatingObject.GetType()];
if (validator is IValidator<T> typedValidator)
{
return typedValidator.Validate(validatingObject);
}
else throw new UnknownValidationType($"No known validator for type of {validatingObject.GetType()}");
}
}
public class ServiceUser
{
private readonly ValidationService validationService;
public ServiceUser(ValidationService validationService)
{
this.validationService = validationService;
}
public void DemonstrateProblem()
{
Widget widget = new Widget() { UniqueIdentifier = Guid.NewGuid() };
Entity entity = new Entity() { Id = 1, SomeProperty = "You know" };
List<object> ObjectsToBeValidated = new List<object>() { widget, entity };
foreach(var t in ObjectsToBeValidated)
{
validationService.Validate(t);//The Generic type of T is Object because that is the type of the List.
//How to get to be the concrete type of Widget and Entity?
}
}
}
public class UnknownValidationType : Exception {
public UnknownValidationType(string message) : base(message)
{
}
}
}
Given the following code:
static class StaticClass
{
public static void DoSomething(BaseClass Value)
{
}
}
abstract class BaseClass
{
}
class DerivedClassForString : BaseClass
{
public string Value { get; }
public DerivedClassForString(string Value)
{
this.Value = Value;
}
public static implicit operator DerivedClassForString(string Value)
{
return new DerivedClassForString(Value);
}
}
class DerivedClassForInt32 : BaseClass
{
public int Value { get; }
public DerivedClassForInt32(int Value)
{
this.Value = Value;
}
public static implicit operator DerivedClassForInt32(int Value)
{
return new DerivedClassForInt32(Value);
}
}
I want to be able to do the following:
StaticClass.DoSomething("Hello world!"); //This should create an instance of DerivedClassForString
StaticClass.DoSomething(16); //This should create an instance of DerivedClassForInt32
This however does not work.
Is there any way to give the compiler a hint to go through the derived classes and search for the implicit resolver?
An other way of doing it would be defining the implicit conversions within BaseClass itself :
abstract class BaseClass
{
public static implicit operator BaseClass(string Value)
{
return new DerivedClassForString(Value);
}
public static implicit operator BaseClass(int Value)
{
return new DerivedClassForInt32(Value);
}
}
Depending on what StaticClass.DoSomething and BaseClass really does, you could make both BaseClass and StaticClass.DoSomething generic :
static class StaticClass
{
public static void DoSomething<T>(BaseClass<T> Value)
{
}
}
class BaseClass<T>
{
public T Value { get; }
public BaseClass(T Value)
{
this.Value = Value;
}
public static implicit operator BaseClass<T>(T Value)
{
return new BaseClass<T>(Value);
}
}
If you want the compiler to infer T when calling StaticClass.DoSomething you'll need to make DoSomething look like this though :
static class StaticClass
{
public static void DoSomething<T>(T Value)
{
BaseClass<T> realValue = Value;
}
}
I have the following code for supporting a list of different types :
public enum eType
{
tInt,
tString,
tDateTime
}
public interface ICustomType<out T>
{
T Value { get; }
}
public abstract class DifferentType
{
protected DifferentType(eType type, string mnemonic)
{
Type = type;
Mnemonic = mnemonic;
}
public string Mnemonic { get; private set; }
public eType Type { get; private set; }
}
public class DateTimeType : DifferentType, ICustomType<DateTime>
{
public DateTimeType(DateTime value, string mnemonic)
: base(eType.tDateTime, mnemonic)
{
Value = value;
}
public DateTime Value { get; private set; }
}
public class IntType : DifferentType, ICustomType<int>
{
public IntType(int value, string mnemonic)
: base(eType.tInt, mnemonic)
{
Value = value;
}
public int Value { get; private set; }
}
public class StringType : DifferentType, ICustomType<string>
{
public StringType(string value, string mnemonic)
: base(eType.tString, mnemonic)
{
Value = value;
}
public string Value { get; private set; }
}
public static class UtilValue
{
public static T GetValue<T>(DifferentType customType)
{
return ((ICustomType<T>)customType).Value;
}
}
public class testTypes2
{
public testTypes2()
{
var values = new List<DifferentType> { GetInt(), GetString(), GetDate() };
foreach (var i in values)
{
switch (i.Type)
{
case eType.tInt:
int resInt = UtilValue.GetValue<int>(i);
break;
case eType.tString:
string resString = UtilValue.GetValue<string>(i);
break;
case eType.tDateTime:
DateTime resDateTime = UtilValue.GetValue<DateTime>(i);
break;
}
}
}
private DateTimeType GetDate()
{
return new DateTimeType(new DateTime(2000, 1, 1), "MnemonicDate");
}
private IntType GetInt()
{
return new IntType(5, "MnemonicInt");
}
private StringType GetString()
{
return new StringType("ok", "MnemonicString");
}
}
and would like to avoid the cast at line return ((ICustomType<T>)customType).Value; in the UtilValue class, any idea how I can get rid of that while still keeping the design?
I am not even sure if this cast is expensive to do? My guess is most certainly.
Visitor-pattern example:
interface IDifferentTypeVisitor
{
void Visit(DateTimeType dt);
void Visit(StringType st);
}
class DifferentType
{
public abstract void Accept(IDifferentTypeVisitor visitor);
}
class DateTimeType : DifferentType
{
public void Accept(IDifferentTypeVisitor visitor)
{
visitor.Visit(this);
}
}
class StringType : DifferentType
{
public void Accept(IDifferentTypeVisitor visitor)
{
visitor.Visit(this);
}
}
class SomeVisitor : IDifferentTypeVisitor
{
public void Visit(DateTimeType dt)
{
//DateTime resDateTime = dt.Value; Or similar
}
public void Visit(StringType st)
{
//string resString = st.Value; Or similar
}
}
public class testTypes2
{
public testTypes2()
{
var values = new List<DifferentType> { /* Content */ };
var visitor = new SomeVisitor();
foreach (var i in values)
{
i.Accept(visitor);
}
}
}
In C# 4 with dynamic it's possible to save some code by adding this to DifferentType:
public void Accept(IDifferentTypeVisitor visitor)
{
visitor.Visit((dynamic)this);
}
and then delete all other Accept methods. It hurts performance but it looks better ;-)
Basically, what I want to do, is:
public class MySpecialCollection<T>
where T : ISomething { ... }
public interface ISomething
{
public ISomething NextElement { get; }
public ISomething PreviousElement { get; }
}
public class XSomething : ISomething { ... }
MySpecialCollection<XSomething> coll;
XSomething element = coll.GetElementByShoeSize(39);
XSomething nextElement = element.NextElement; // <-- line of interest
... without having to cast nextElement to XSomething. Any ideas?
I would have wanted something in the kind of ...
public interface ISomething
{
public SameType NextElement { get; }
public SameType PreviousElement { get; }
}
Thank you in advance!
Make the interface generic:
public class MySpecialCollection<T> where T : ISomething<T> {
...
}
public interface ISomething<T> {
T NextElement { get; }
T PreviousElement { get; }
}
public class XSomething : ISomething<XSomething> {
...
}
Well, you can do it using an implicit operator (though I'm not 100% sure it will work in this case):
public static XSomething operator implicit(ISomething sth)
{
return (XSomething)sth;
}
But note that this is clearly not a very good idea; the cleanest way is to do an explicit cast.
I'd recommend making the interface generic so the types of the properties can be the interface's generic type.
using System;
namespace ConsoleApplication21
{
public interface INextPrevious<out TElement>
{
TElement NextElement { get; }
TElement PreviousElement { get; }
}
public class XSomething : INextPrevious<XSomething>
{
public XSomething NextElement
{
get { throw new NotImplementedException(); }
}
public XSomething PreviousElement
{
get { throw new NotImplementedException(); }
}
}
public class MySpecialCollection<T>
where T : INextPrevious<T>
{
public T GetElementByShoeSize(int shoeSize)
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
var coll = new MySpecialCollection<XSomething>();
XSomething element = coll.GetElementByShoeSize(39);
XSomething nextElement = element.NextElement;
}
}
}