我有以下代码:
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
}
}
我将代码简化为显示结构。
现在我需要associationDictionary,它将返回IOperandFactory
所需的Type
:
像这样:
var factoryDict =
new Dictionary<Type, IOperandFactory<>>() { { typeof(double), new DoubleFactory() } };
如果有可能,你能帮我实现吗?
答案 0 :(得分:7)
为此,您需要具有非通用接口(通常除了通用接口之外),即非通用Operand
,带Operand<T> : Operand
(也可以是接口) )和带有IOperandFactory
的非通用IOperandFactory<T> : IOperandFactory
。唯一的另一种选择是存储Dictionary<Type, object>
,并根据需要调用调用者。
以下是非通用方法:
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()}
};
}
}
答案 1 :(得分:2)
如果我理解正确,您正在尝试存储泛型类型的集合,其中泛型类型参数可能会有所不同。如果是这种情况,则无法直接进行,如下例所示:
// 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? ... */ >>();
这里显而易见的是,无法推断出要使用的类型参数。相反(关于你的例子),你可能想要这样的东西:
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() }
};
}
}
这可能不是最优雅的解决方案,但它允许您在同一个集合中存储不同的泛型类型。然而,这个问题是访问这样一个集合的调用者需要知道要转换为什么类型。例如:
// ... Inside SomeContainer ...
public IOperandFactory<T> GetFactory<T>()
{
return (IOperandFactory<T>)factoryDict[typeof(T)];
}
因此,您可以使用
获取DoubleFactory
IOperandFactory<double> doubleFactory = mSomeContainerInstance.GetFactory<double>();
IOperand<double> emptyOperand = doubleFactory.CreateEmptyOperand();
IOperand<double> filledOperand = doubleFactory.CreateOperand(1.0d);