某些泛型类的类属性强制转换为泛型类型来执行方法
首先我想为混乱的标题道歉。我不太清楚如何将其写入文字,因此我将描述情况。某些泛型类的类属性强制转换为泛型类型来执行方法
我正在写一个比较引擎为我们的产品,也就是能够在不同的产品比较类似这样的:ComparableProduct,增加财产
:public abstract class ComparableProduct
{
public ComparableProperty<decimal> Weight { get; set; }
public ComparableProperty<decimal> Width { get; set; }
public ComparableProperty<decimal> Height { get; set; }
public ComparableProperty<decimal> Depth { get; set; }
public bool IsBetterThan(ComparableProduct target){}
}
实际的产品是由ComparableProduct,如屏幕衍生
ComparableProperty<decimal> Dimension { get; set; }
这意味着我可以有一个类的笔记本电脑,它有一个属性键盘,屏幕,StorageDevice等等,这些都是从ComparableProduct派生的。
那些有反过来可比性质是这样的:
public abstract class ComparableProperty<T> where T : IComparable<T>
{
T Value { get; set; }
public ComparisonType ComparisonType { get; set; }
public bool IsBetterThan(T target)
{
if(ComparisonType == ComparisonType.GreaterThan)
return Value.CompareTo(target) >= 0;
return Value.CompareTo(target) <= 0;
}
public bool IsBetterThan(IEnumerable<T> targets)
{
foreach(var target in targets)
{
if (ComparisonType == ComparisonType.SmallerThan && Value.CompareTo(target) >= 0)
return false;
if (ComparisonType == ComparisonType.GreaterThan && Value.CompareTo(target) <= 0)
return false;
}
return true;
}
}
我没有测试过这些,通过他们应该工作的所有逻辑。我遇到的麻烦是与ComparableProduct中的IsBetterThan方法。预期的功能是在顶级类(比如Laptop)上通过其ComparableProduct属性循环,并为另一个副本调用IsBetterThan,并且这些将通过它们的子属性循环...此外,所有ComparableProduct ComparableProperty属性都使用IsBetterThan与其他班级的同等价值。
无论如何,这是我的,你可以立即看到我遇到的问题。
public bool IsBetterThan(ComparableProduct target)
{
foreach(var property in GetType().GetProperties().Where(x => x.PropertyType == typeof(ComparableProduct)))
{
var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as ComparableProduct;
var local = property.GetValue(this, null) as ComparableProduct;
if(local != null && !local.IsBetterThan(compareTo))
return false;
}
foreach(var property in GetType().GetProperties().Where(x => x.PropertyType == typeof(ComparableProperty<>)))
{
var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as ComparableProperty<>;
var local = property.GetValue(this, null) as ComparableProperty<>;
if(local != null && !local.IsBetterThan(compareTo))
return false;
}
}
正如你所看到的,我试图将它转换为ComparableProperty <>,这意味着它缺少泛型类型。但是,我不太清楚如何获取相关属性的泛型类型。
另外,如果还有更好的方法,我会采取任何可以提示的方式,但这是我想到的第一个体面的做法。
编辑:
轮辐太快。当我试图枚举ComparableProduct的IsBetterThan属性是这样的:
foreach(var property in GetType().GetProperties())
{
var t = property.GetType().GetInterfaces();
if (!property.GetType().GetInterfaces().Contains(typeof(IComparableProperty))) continue;
var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as IComparableProperty;
var local = property.GetValue(this, null) as IComparableProperty;
if (local == null) continue;
if(!local.IsBetterThan(compareTo))
return false;
}
然后,它似乎无法在界面找到IComparableProperty。我已经经历了可能包含它的主要方法......但唯一包含的接口是ICustomAttributeProvider,_MemberInfo,_PropertyInfo和ISerializable。
编辑2:
我已经通过字符串比较落回
if (property.PropertyType.Name != "ComparableProperty`1") continue;
并改变吨至ComparableProperty和IEnumerable到IEnumerable的>整个比较完美的作品后,解决了这个。
您可以创建一个非通用接口,然后用它的工作:
public interface IComparableProperty
{
bool IsBetterThan(object target);
bool IsBetterThan(IEnumerable targets);
}
public abstract class ComparableProperty<T>: IComparableProperty where T : IComparable<T>
{
T Value { get; set; }
public ComparisonType ComparisonType { get; set; }
public bool IsBetterThan(T target)
{
if (ComparisonType == ComparisonType.GreaterThan)
return Value.CompareTo(target) >= 0;
return Value.CompareTo(target) <= 0;
}
public bool IsBetterThan(IEnumerable<T> targets)
{
foreach (var target in targets)
{
if (ComparisonType == ComparisonType.SmallerThan && Value.CompareTo(target) >= 0)
return false;
if (ComparisonType == ComparisonType.GreaterThan && Value.CompareTo(target) <= 0)
return false;
}
return true;
}
bool IComparableProperty.IsBetterThan(object target)
{
return IsBetterThan((T) target);
}
bool IComparableProperty.IsBetterThan(IEnumerable targets)
{
return IsBetterThan((IEnumerable<T>) (targets));
}
}
编辑0:
你尝试使用此方法Type.IsAssignableFrom(类型):像这样:
foreach (var property in GetType().GetProperties())
{
if (!typeof(IComparableProperty).IsAssignableFrom(property.PropertyType)) continue;
var compareTo = target.GetType().GetProperty(property.Name).GetValue(target, null) as IComparableProperty;
var local = property.GetValue(this, null) as IComparableProperty;
if (local == null) continue;
return local.IsBetterThan(compareTo);
}
哦,亲爱的,我没有睡觉时,我似乎失去了50%的智力。这的确是解决方案,谢谢! – NeroS 2013-04-20 19:56:50
说得太快。编辑OP澄清。 – NeroS 2013-04-20 20:50:13
对,答案在技术上仍然解决了我原来的问题,所以我会接受它。使用特定的界面做了这个窍门,但如果我想使用强大的打字功能,我仍然需要弄清楚它的一部分:) – NeroS 2013-04-21 00:38:23