我正在尝试用c#代码找出一些东西,而且我不是百分之百确定它是否可行,但我正在尝试为几个类实现搜索功能,这些功能简化并且易于开发。现在我有以下代码:
[DataContract(IsReference = true), Serializable]
public class ClassSearch
{
[DataMember]
public string Name { get; set; }
[DataMember]
public object Value { get; set; }
public override string ToString()
{
return String.Format("{0} = {1}", Name, Value);
}
... // additional logic
}
但是,我想为对象值包含强类型,以便它只能被设置为传入的属性,我想类似(假设,不确定这是否可行)
[DataContract(IsReference = true), Serializable]
public class ClassSearch<TProperty>
{
[DataMember]
public TProperty Property {get; set; }
public override string ToString()
{
return String.Format("{0} = '{1}'", Property.Name, Property);
}
... // additional logic
}
public class MainClass
{
public void Execute()
{
SomeClass someClass = new Class{
Property = "Value";
};
ClassSearch search = new ClassSearch<SomeClass.Property>{
Property = someClass.Property
};
var retString = search.ToString(); // Returns "Property = 'Value'"
}
}
答案 0 :(得分:0)
您似乎正在尝试创建一个WCF服务,以便能够传递您喜欢的任何类型。
首先,这不是WSDL友好的。所有WCF服务都需要能够在WSDL中公开。 WSDL是关于明确定义的合同,因此需要全部定义类型。因此通用方法不起作用 - 主要是因为WSDL。话虽如此,你仍然可以使用泛型,但是你必须使用KnownType
并实际定义所有可能的类型 - 这对我来说是打败了对象。
然而,您可以做的一件事就是自己序列化对象并在线上传递其类型名称。另一方面,你可以把它反序列化。
这就是:
// NOTE: Not meant for production!
[DataContract]
public class GenericWcfPayload
{
[DataMember]
public byte[] Payload {get; set;}
[DataMember]
public string TypeName {get; set;}
}
答案 1 :(得分:0)
如果没有更简单的答案,我会用这个来尝试。
您可以像这样使用表达式:
// Sample object with a property.
SomeClass someClass = new SomeClass{Property = "Value"};
// Create the member expression.
Expression<Func<object /*prop owner object*/, object/*prop value*/>> e =
owner => ((SomeClass)owner).Property;
// Get property name by analyzing expression.
string propName = ((MemberExpression)e.Body).Member.Name;
// Get property value by compiling and running expression.
object propValue = e.Compile().Invoke(someClass);
您通过成员表达式owner => ((SomeClass)owner).Property
移交您的财产。此表达式包含您需要的所有信息:属性名称和属性值。最后两行显示了如何获取名称和值。
遵循更大的示例:
class MainClass
{
public static void Execute()
{
SomeClass someClass = new SomeClass{
Property = "Value"
};
var search = new ClassSearch(s => ((SomeClass)s).Property);
Console.Out.WriteLine("{0} = '{1}'", search.Property.Name, search.Property.GetValue(someClass));
}
}
class Reflector
{
public static string GetPropertyName(Expression<Func<object, object>> e)
{
if (e.Body.NodeType != ExpressionType.MemberAccess)
{
throw new ArgumentException("Wrong expression!");
}
MemberExpression me = ((MemberExpression) e.Body);
return me.Member.Name;
}
}
class ClassSearch
{
public ClassSearch(Expression<Func<object, object>> e)
{
Property = new PropertyNameAndValue(e);
}
public PropertyNameAndValue Property { get; private set; }
public override string ToString()
{
return String.Format("{0} = '{1}'", Property.Name, Property);
}
}
class PropertyNameAndValue
{
private readonly Func<object, object> _func;
public PropertyNameAndValue(Expression<Func<object, object>> e)
{
_func = e.Compile();
Name = Reflector.GetPropertyName(e);
}
public object GetValue(object propOwner)
{
return _func.Invoke(propOwner);
}
public string Name { get; private set; }
}
class SomeClass
{
public string Property { get; set; }
}
该示例的主要部分是方法 Reflector.GetPropertyName(...)
,它返回表达式中属性的名称。即Reflector.GetPropertyName(s => ((SomeClass)s).Property)
会返回“Property”。
优势是:这是类型安全的,因为如果 SomeClass 没有属性'{em>,new ClassSearch(s => s.Property)
编译会以错误结束Property
”。
缺点是:这不是类型安全的,因为如果您写例如: new ClassSearch(s => s.Method())
并且会有一个方法' Method
'然后就会出现编译错误,但会出现运行时错误。