不是按名称指定接口成员,而是键入
我有一些来自某些外部WSDL文件的svcutil生成的类似类。 任何类都有一个Header
属性和string
属性,它名为class name + "1"
。
例如,我有类:具有Header
属性和SimpleRequest1
属性的SimpleRequest1
。
另一个是具有Header
属性和ComplexRequest1
属性的ComplexRequest1
。
所以,我想为这些类创建一个通用接口。 所以,基本上我可以定义类似的东西:
interface ISomeRequestClass { string Header; // here is some definition for `class name + "1"` properties... }
是否可以在界面中定义这样的成员?
这是post编辑去…
以下是生成的类的示例:
[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; } }
编辑后2
我改变了这个恼人的+1属性的定义来表示真实的实际图片。 它们都有不同的类型。 那么如何将它拉出到通用接口呢?
编辑后3
这是一个可以带来更多澄清的耦合问题 。
编辑 (看到你的代码示例后):从技术上讲,你的代码没有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; } } }
您可以更一般地定义您的界面:
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; } } }
暂时搁置你的类和属性的命名。
如果您要创建一个具有与您的特定+1类型相关的属性的界面,您有几个选项。
使用+ 1的基类
如果您的两个+1类都inheritance自相同的基类,则可以在接口定义中使用它:
public interface IFoo { [...] PlusOneBaseType MyPlusOneObject{get;set;} }
在您的界面上创建一个通用属性
此方法允许您将+1属性的类型指定为通用参数:
public interface IFoo { [...] TPlusOneType MyPlusOneObject{get;set;} }
您可以使用哪个:
public class SimpleRequest : IFoo { [...] }
更新
鉴于您的类是部分类,您可以始终创建部分类的第二个(非机器生成的)版本,它可以实现您的界面。
你提到过svcutil所以我假设你使用这些类作为WCF DataContracts?
如果是这种情况,那么您可以使用DataMemberAttribute
的name
属性。
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;
你真的需要这些类有一个共同的接口吗? 我很想创建一个包装器接口(或者只是一个具体的类),然后可以使用reflection来访问有问题的字段:
// TODO: Make this class implement an appropriate new interface if you want // to, for mocking purposes. public sealed class RequestWrapper { 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); } } }
如果reflectioncertificate太慢,你可以使用表达式树来为此构建委托,但我会坚持一个简单的解决方案来开始。
这样做的好处是你只需要编写一次这个代码 – 但它确实意味着创建一个围绕真实请求对象的包装器,而部分类的答案却没有。
上述就是C#学习教程:不是按名称指定接口成员,而是键入分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/943093.html