Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以在WCF服务中公开私有方法?_C#_Wcf_.net 4.5 - Fatal编程技术网

C# 为什么可以在WCF服务中公开私有方法?

C# 为什么可以在WCF服务中公开私有方法?,c#,wcf,.net-4.5,C#,Wcf,.net 4.5,为什么我们可以将[OperationContract]属性放在wcf服务中的私有方法上。从我开始编程的那天起,我就被教会了一些私人方法,这些方法在课堂外是无法使用的。现在在WCF服务中,您可以公开私有方法 [ServiceContract] public class MyServices { [OperationContract] private int add(int a,int b) { retu

为什么我们可以将[
OperationContract
]属性放在wcf服务中的私有方法上。从我开始编程的那天起,我就被教会了一些私人方法,这些方法在课堂外是无法使用的。现在在WCF服务中,您可以公开私有方法

    [ServiceContract]
    public class MyServices
    {
        [OperationContract]
        private int add(int a,int b)
        {
            return a + b;
        }
    }
不知道为什么它是这样设计的,但如果你检查来源,第336行说

internal const BindingFlags ServiceModelBindingFlags=BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance

请特别注意非公开标志。然后,当WCF使用反射来确定要公开哪些方法时,将在第678行使用此选项:

   static List<MethodInfo> GetMethodsInternal(Type interfaceType)
   {
            List<MethodInfo> methods = new List<MethodInfo>();
            foreach (MethodInfo mi in interfaceType.GetMethods(ServiceModelBindingFlags))
            {
                if (GetSingleAttribute<OperationContractAttribute>(mi) != null)
                {
                    methods.Add(mi);
                }
                ...
静态列表GetMethodsInternal(类型interfaceType)
{
列表方法=新列表();
foreach(interfaceType.GetMethods(ServiceModelBindingFlags)中的MethodInfo mi)
{
如果(GetSingleAttribute(mi)!=null)
{
方法:添加(mi);
}
...
我同意你的看法,这是一个奇怪的决定,但WCF开发者明确决定通过加入非公开标志来实现这一点


发现它可以工作很有趣。当然,您可以使用私有访问修饰符来拒绝类的使用者访问标记的成员。但是WCF将您标记为
OperationContract
属性的每个方法公开给public。正如Robert Levy所发现的,它是以这种方式实现的。类似地,您可以在这方面找到一些信息,特别是嗯

当您检查时,您可能会注意到他们在私有方法上使用OperationContract属性。但这似乎是一个输入错误,因为类必须实现其接口的方法

无论如何,对于开发人员来说,最安全的方法是在服务类接口中使用
ServiceContract
OperationContract
属性,例如:

[ServiceContract]
public interface IMyService 
{
    [OperationContract]
    string GetData();
}

public class MyService : IMyService 
{
    public string GetData() { ... }
    private string ComputeData() { ... } // this one is not visible to clients
}
2美分:

WCF使用的SOAP不遵循C#的OOPs概念。另一个“异常”是方法重载,这是一个非常有用且广泛使用的C#特性。虽然我们可以重载服务类中的方法,但我们不能有两个同名的OperationContract(即使签名不同),这意味着我们不能在SOAP上公开重载方法。这样,它将表明,由于作用域说明符不是SOAP特性,WCF将忽略它,并通过OperationContract和DataMember属性来决定契约

以下内容也将作为DataContract的DataMember公开:

[DataMember]
private int _personAge;

您可以使用此属性标记您的方法,但它对服务客户端不可见。您是否确认该属性实际上可以通过WCF调用?(可能是-我没有尝试过)。从根本上说,不能说“此属性只能应用于公共成员”@JohnSaunders是的,没错。我刚刚创建了新的WCF服务项目,删除了IService1接口,并将所有协定属性移动到类定义中。然后我添加了新的私有方法,并将其标记为OperationContract。然后我创建了新的控制台应用程序,向我的WCF服务添加了服务引用,私有方法也被发现我成功地从控制台应用程序调用了私有方法。WCF服务托管在本地IIS Express上。问题可能不是你为什么可以这样做,而是你为什么要这样做。你是程序员,只是不要在你的私有方法上使用该属性。除了Patrick说的,你应该使用using服务协定接口并将属性放置在接口方法上。创建没有接口的服务会强制您使用有其自身问题的服务引用Robert,对于那些问题不明显的人,您应该解释WCF通过Reflection@JohnSaunders-作出调整