好吧,我總是可以硬編碼檢查屬性以解決我的情況,但我想使用反射來做到這一點。
我的通用型別:
public class AnalyzedParameter<T>
{
public T Value { get; set; }
public bool Valid { get; set; }
}
我的課:
public class Foo
{
public AnalyzedParameter<int> A { get; set; }
public AnalyzedParameter<string> B { get; set; }
}
我需要AnalyzedParameter通過檢查Valid內部的屬性來檢查具有型別的每個屬性。
所以我的方法必須是這樣的:
public bool IsValid()
{
var props = GetType().GetProperties().Where(prop => prop.PropertyType == typeof(AnalyzedParameter<>));
var valid = props.All(p => ((AnalyzedParameter<object>) p.GetValue(this)).Valid);
return valid;
}
但它不起作用。有任何想法嗎?
uj5u.com熱心網友回復:
這不起作用,因為PropertyType您的實體變數的of 不是AnalyzedParameter<>而是而是AnalyzedParameter<int>or AnalyzedParameter<string>。
您可能需要列舉您希望檢查的型別,并從中構造具體型別。例如,在我放在一起的一些測驗代碼中:
public class AnalyzedParameter<T>
{
public T Value { get; set; }
public bool Valid { get; set; } = false;
}
public class Foo
{
public AnalyzedParameter<int> A { get; set; }
public AnalyzedParameter<string> B { get; set; }
public bool IsValid()
{
var thisType = GetType();
Log.Verbose($"Type: {thisType}");
var thisProperties = thisType.GetProperties();
Log.Verbose($"Properties: {thisProperties}");
foreach (PropertyInfo pi in thisProperties)
{
Log.Verbose($"type:{pi.PropertyType}, name:{pi.Name}");
if (pi.PropertyType == typeof(AnalyzedParameter<>)) Log.Verbose("This property is an AnalyzedParameter<>");
if (pi.PropertyType == typeof(AnalyzedParameter<int>)) Log.Verbose("This property is an AnalyzedParameter<int>");
if (pi.PropertyType == typeof(AnalyzedParameter<string>)) Log.Verbose("This property is an AnalyzedParameter<string>");
}
}
}
[10:25:50 VRB] Type: FooTest.Foo
[10:25:50 VRB] Properties: System.Reflection.PropertyInfo[]
[10:25:50 VRB] type:FooTest.AnalyzedParameter`1[System.Int32], name:A
[10:25:50 VRB] This property is an AnalyzedParameter<int>
[10:25:50 VRB] type:FooTest.AnalyzedParameter`1[System.String], name:B
[10:25:50 VRB] This property is an AnalyzedParameter<string>
uj5u.com熱心網友回復:
第一部分直接回答您的問題 - 如何使您正在做的作業發揮作用。第二個希望改變問題并使其更容易。
我將檢查所有這些Valid屬性的部分分離到一個單獨的類中,以使我更容易使用。(如果這只是為了Foo那么你就不需要反射。你已經知道屬性Foo有什么。
public static class Validations
{
// x is a Foo or any other object that
// has properties of type AnalyzedProperty<T>
public static bool IsValid(object x)
{
var analyzedParameterProperties = x.GetType()
.GetProperties().Where(prop =>
prop.PropertyType.GetGenericTypeDefinition() == typeof(AnalyzedParameter<>));
var isValid = analyzedParameterProperties.All(analyzedParameterProperty =>
GetIsValidValue(x, analyzedParameterProperty));
return isValid;
}
private static bool GetIsValidValue(object x, PropertyInfo analyzedParameterProperty)
{
var analyzedParameter = analyzedParameterProperty.GetValue(x);
if (analyzedParameter == null) return false; // or true?
var analyzedParameterIsValidProperty = analyzedParameter.GetType()
.GetProperty("Valid", typeof(bool));
return (bool)analyzedParameterIsValidProperty.GetValue(analyzedParameter);
}
}
該IsValid方法接受一個物件(如 的實體Foo)并檢索型別與開放泛型型別匹配的所有屬性AnalyzedParameter<>。
混亂的部分是您不能使用開放的泛型型別來讀取Valid每個AnalyzedParameter物件的屬性。
所以第二種方法—— GetIsValidValue
- 獲取屬性的值 - 一個
AnalyzedParameter物件 - 查找
Valid回傳的屬性bool - 讀取該屬性并回傳其值。
如果AnalyzedProperty<T>實作一些具有該Valid屬性的介面,這會容易得多。在這種情況下,您可以將每個屬性值轉換為該介面并以這種方式讀取屬性,而不是使用反射來查找Valid屬性。
public class AnalyzedParameter<T> : IHasValidation
{
public T Value { get; set; }
public bool Valid { get; set; }
}
public interface IHasValidation
{
public bool Valid { get; set; }
}
現在剩下的代碼可以簡單一點:
public static bool IsValid(object x)
{
var analyzedParameterProperties = x.GetType()
.GetProperties().Where(prop =>
typeof(IHasValidation).IsAssignableFrom(prop.PropertyType));
var analyzedParameterValues = analyzedParameterProperties.Select(property =>
property.GetValue(x)).Cast<IHasValidation>();
// This assumes that if the property is null, it's not valid.
// You could instead check for value is null or .Valid == true.
var isValid = analyzedParameterValues.All(value => value?.Valid == true);
return isValid;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/364121.html
下一篇:如何使用變數作為物件的名稱?
