类的强类型搜索功能
本文关键字:功能 搜索 强类型 | 更新日期: 2023-09-27 18:27:05
我正在尝试用c#代码找出一些东西,我不能100%确定这是否可能,但我正在尝试为几个类实现搜索功能,这些功能经过了简化,总体上易于开发。现在我有以下代码:
[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'"
}
}
您似乎正在尝试创建一个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;}
}
如果没有更简单的答案,我会试试这个
您可以使用表达式,如下所示:
// 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)
将返回"属性"。
的优点是:这是类型安全的,因为在new ClassSearch(s => s.Property)
中,如果SomeClass没有属性"Property
",编译将以错误结束。
的缺点是:这不是类型安全的,因为如果您编写例如new ClassSearch(s => s.Method())
,并且会有一个方法"Method
",则不会有编译错误,而是运行时错误。