我有定义值和少量操作的界面:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
然后我基于该接口实现类
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
现在我想制作操作于值池并使用泛型的通用操纵器(所以我只写一次)。由于我将来想要使用这个类的方式,它不能被声明为static。将泛型类型移动到方法中也没有任何好处。 我能得到的最接近的是:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
这个ValueManipulator类的主要问题是我需要知道DoubleValue中使用的IV的IV(在本例中为double)。所以它看起来像这样:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
如何创建ValueManipulator,以便用户不需要知道值实现中使用的是什么类型?
答案 0 :(得分:2)
好吧,如果您的ValueManipulator<T>
没有状态,根据您的代码片段似乎是您的情况,那么只需将方法设为通用而不是类,这样就可以利用类型推断。
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
现在你可以做到:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
如果这是一个有效的解决方案,那么考虑将ValueManipulator
作为静态类:
ValueManipulator.Manipulate(ProvideDoubles());
Pd积。请按照评论中的建议进行操作,并将ValueType
更改为其他一些不那么令人困惑的名称。
更新在对您的问题进行最新编辑后,您明确指出ValueManipulator<T>
具有状态,解决方案似乎正在实施静态工厂类:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
再次让类型推断完成它的工作:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());