0

我在 cricles 中四处改变和重新改变,不明白为什么我没有得到我想要的价值观,也许有人可以解释一下。

我有这个对象

var result = new GetRatePlanListResponse
        {
            RatePlanId = prodRpsResult.Id,
            RatePlanName = prodRpsResult.Name,
            EffectiveStartDate = prodRpsResult.EffectiveStartDate,
            EffectiveEndDate = prodRpsResult.EffectiveEndDate,
            BillingPeriod = prodRpsResult.PRDP_BillingFrequency__c.HasValue ? prodRpsResult.PRDP_BillingFrequency__c.Value.ToString() : null,
            ShippingSchedule = prodRpsResult.PRDP_DeliveryFrequency__c.HasValue ? prodRpsResult.PRDP_DeliveryFrequency__c.Value.ToString() : null,
            UsageLevel = prodRpsResult?.PRDP_UsageLevel__c,
            IncludedUnits = prodRpsResult?.PRDP_NumberofPackages__c,
            BasePrice = new RatePlanBasePrice
            {
                Currency = pricing != null ? pricing.Currency : string.Empty,
                Price = pricing != null && pricing.Price != null ? pricing.Price.Value : 0
            }
        };

然后我用那个对象调用这个函数有参数:

    public void PriceConverter<T>(ref T obj)
    {
        Type t = obj.GetType();

        foreach (var prop in t.GetProperties())
        {
            if (Enum.GetNames(typeof(RootPrices)).Any(x => x.ToLower() == prop.Name.ToLower()))
            {
                prop.SetValue(obj, ((int)(double.Parse((string)prop.GetValue(obj)) * 100)).ToString(), null);
            }
            
        }

    }

我的问题是由于某种原因我无法访问值货币和价格。我怎样才能做到这一点?

编辑:

好的,谢谢大家提供的信息,我决定改变我的方法,因为如果它们内部有其他对象,我无法更改通用对象属性,因为它们代表不同的引用。尽管我正在更改它,但如果有人知道一种递归或迭代更改引用对象及其引用的所有对象并可以提供解决方案的方法,我将不胜感激具有相似字段的预先存在的代码库的多个对象数据。

4

2 回答 2

0

两者CurrencyPrice属于RatePlanBasePrice类型 not to GetRatePlanListResponse。所以,你必须先获得BasePrice财产。如果RatePlanBasePrice是一个(不是struct):

  using System.Linq;
  using System.Reflection;

  ...  

  var prop = obj
    .GetType()
    .GetProperties()
    .FirstOrDefault(p => 
      string.Equals("BasePrice", p.PropertyType) &&
      p.CanRead &&
      typeof(RatePlanBasePrice).IsAssignableFrom(p.PropertyType));

  if (prop != null) {
    obj val = prop.GetValue(obj);

    if (val != null) {
      RatePlanBasePrice value = (RatePlanBasePrice) val;

      // Put relevant code here 
      val.Currency = ...
      val.Price = ...
    }
  }

如果 IfRatePlanBasePrice是一个结构

  var prop = obj
    .GetType()
    .GetProperties()
    .FirstOrDefault(p => 
      string.Equals("BasePrice", p.PropertyType) &&
      p.CanRead && 
      p.CanWrite &&
      typeof(RatePlanBasePrice).IsAssignableFrom(p.PropertyType));

  if (prop != null) {
    // uncomment, if you need an old value  
    //var oldValue = (RatePlanBasePrice) (prop.GetValue(obj));

    prop.SetValue(obj, new RatePlanBasePrice() {
      // Put relevant code here
      Currency = ...
      Price = ... 
    });
  }

编辑:是的,您可以遍历属性,但是为什么呢?如果您使用Linq,放置一个查询是很自然的。如果您正在寻找某种通用案例,让我们提取一个方法:

private static bool TryReadProperty<T>(object source, string name, out T value) {
  value = default(T);

  if (null == source)
    return false;

  var prop = source
    .GetType()
    .GetProperties()
    .FirstOrDefault(p => string.Equals(p.Name, name) &&
                         p.CanRead &&
                         typeof(T).IsAssignableFrom(p.PropertyType));

  if (null == prop)
    return false;

  value = (T) (prop.GetValue(prop.GetGetMethod().IsStatic ? null : source));

  return true;
}

那么你可以使用它

if (TryGetProperty<RatePlanBasePrice>(obj, "BasePrice", out var value)) {
  // Put relevant code here 
  val.Currency = ...
  val.Price = ...
}
于 2021-04-12T18:34:00.063 回答
0

您可以PriceConverter<T>递归调用每个propertyin的值t。如果您不想调用PriceConverter<T>特定类型的属性,则需要实现某种过滤。

对于您给出的简单示例,您可能只需要获得可读的可变属性即可。此外,看起来ref关键字不是必需的,因为您可能会改变obj的属性,但实际上并未更改引用。

void PriceConverter<T>(T obj)
{
    Type t = obj.GetType();
    foreach (var prop in t.GetProperties().Where(p => p.CanRead && p.CanWrite))
    {
        object value = prop.GetValue(obj);
        if (value != null)
        {
            PriceConverter(value);
        }

        if (Enum.GetNames(typeof(RootPrice)).Any(x => x.ToLower() == prop.Name.ToLower()))
        {
            prop.SetValue(obj, ((int)(double.Parse((string)prop.GetValue(obj)) * 100)).ToString(), null);
        }
    }
    
}
于 2021-04-12T19:19:58.077 回答