我有很多来自一些外部WSDL文件由SvcUtil工具生成的类似的类的。 任何类有一个Header
属性和string
,其命名属性class name + "1"
。
举例来说,我有类: SimpleRequest
有Header
财产和SimpleRequest1
财产。
另一个是ComplexRequest
有Header
财产和ComplexRequest1
财产。
所以,我想创建这样的类的通用接口。 所以,基本上我可以定义这样的事情:
interface ISomeRequestClass {
string Header;
// here is some definition for `class name + "1"` properties...
}
是否有可能在界面来定义这样的会员吗?
下面是编辑后去...
下面是生成类的样品:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class SimpleRequest
{
public string Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name="SimpleRequest", Namespace="data", Order=0)]
public SimpleRequestMsg SimpleRequest1;
public SimpleRequest()
{
}
public SimpleRequest(string Header, SimpleRequestMsg SimpleRequest1)
{
this.Header = Header;
this.SimpleRequest1 = SimpleRequest1;
}
}
POST EDIT 2
我改变了这个恼人的+1属性的定义,以真正代表实际的画面。 这是所有有不同的类类型。 所以,我怎么也拔不出来常用的接口?
帖子编辑3
这里是加上的问题 ,这会带来更多的澄清。
Answer 1:
编辑 (看到你的代码示例之后):从技术上说,你的代码没有一个Header
属性 ,它有一个Header
字段 。 这是一个重要的区别,因为你不能在指定的接口领域 。 但是,使用下面描述的方法,你可以到你的类,返回的字段值添加属性。
是否有可能在界面来定义这样的会员吗?
不,接口名称不能是动态的。 无论如何,这样的接口不会是非常有用的。 如果你有类的实例ISomeRequestClass
,你会用什么名称来访问该属性?
你可以,但是,使用显式接口实现:
interface ISomeRequestClass {
string Header { get; set; }
string ClassName1 { get; set; }
}
class SomeClass : ISomeRequestClass {
string Header { ... }
string SomeClass1 { ... }
// new: explicit interface implementation
string ISomeRequestClass.ClassName1 {
get { return SomeClass1; }
set { SomeClass1 = value; }
}
}
Answer 2:
你可以更普遍地定义你的界面:
interface ISomeRequestClass {
string HeaderProp {get; set;}
string Prop {get; set;}
}
和你的具体类可以通过绘图界面成员延伸(在一个额外的代码文件),以类字段如下所示:
public partial class SimpleRequest : ISomeRequestClass
{
public string HeaderProp
{
get
{
return Header;
}
set
{
Header = value;
}
}
public string Prop
{
get
{
return SimpleRequest1;
}
set
{
SimpleRequest1= value;
}
}
}
Answer 3:
撇开了片刻类和属性的命名。
如果您正在寻找创建您的具体+1类型相关的属性的接口,你有几个选项。
使用一个基类为您的+1
如果两个+1类从同一个基类继承,你可以在你的接口定义使用:
public interface IFoo
{
[...]
PlusOneBaseType MyPlusOneObject{get;set;}
}
创建接口的通用属性
这种方法允许你指定类型为+1属性作为泛型参数:
public interface IFoo<TPlusOneType>
{
[...]
TPlusOneType MyPlusOneObject{get;set;}
}
您可能需要使用这样的:
public class SimpleRequest : IFoo<SimpleRequest1>
{
[...]
}
更新
鉴于你的类是局部类,你总是可以创建一个第二(产生的非机)是impliments你的接口部分类的版本。
Answer 4:
你提到SvcUtil工具,所以我假设你使用这些类的WCF DataContracts?
如果是这样的话,那么你可以利用name
的属性DataMemberAttribute
。
interface IRequest
{
string Header { get; set; }
string Request1 { get; set; }
}
[DataContract]
class SimpleRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="SimpleRequest1"]
public string Request1 { get; set; }
}
[DataContract]
class ComplexRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="ComplexRequest1"]
public string Request1 { get; set; }
}
如果你担心给自己更多的工作,当你在将来的某个时候重新生成代码,那么我建议你写一个PowerShell脚本来自动完成这个转变。 所有SvcUtil工具后,只需在微软的一些人写的剧本。 这不是魔术或“正确”或“标准”。 脚本可以拨打电话到scvutil再做出几个简单的修改后的文件。
编辑 (看到你的编辑后)
你已经在使用MessageBodyMemberAttribute
的Name
属性,因此只是改变这一点:
public string SimpleRequest1;
至
public string Request1;
Answer 5:
你真的需要这些类有共同的接口? 我会被诱惑,而不是创建一个包装接口(或只是一个具体的类),然后可以使用反射来访问有问题的领域:
// TODO: Make this class implement an appropriate new interface if you want
// to, for mocking purposes.
public sealed class RequestWrapper<TRequest, TMessage>
{
private static readonly FieldInfo headerField;
private static readonly FieldInfo messageField;
static RequestWrapper()
{
// TODO: Validation
headerField = typeof(TRequest).GetField("Header");
messageField = typeof(TRequest).GetField(typeof(TRequest).Name + "1");
}
private readonly TRequest;
public RequestWrapper(TRequest request)
{
this.request = request;
}
public string Header
{
get { return (string) headerField.GetValue(request); }
set { headerField.SetValue(request, value); }
}
public TMessage Message
{
get { return (TMessage) messageField.GetValue(request); }
get { messageField.SetValue(request, value); }
}
}
你可以使用表达式目录树建立代表这个如果反射证明太慢,但我会坚持一个简单的解决方案开始。
这样做的好处是,你只需要一次写这样的代码 - 但它确实意味着创造周围的真实的请求对象,其中部分类的答案没有一个包装。
文章来源: Specify interface member not by name but type