访问修饰符和继承c#

时间:2015-10-29 03:22:48

标签: c# class struct interface access-modifiers

我试图让一个类只允许在命名空间范围内使用new关键字进行初始化。虽然我需要能够使用它的type示例

namespace MyNameSpace {

   class MyClass {

      public string Name { get; set; }
   }

   class NewMyClass {
       MyClass cls = new MyClass();
       cls.Name = "My Name";
   } 
} 

但在Program.cs我希望用户只能执行以下操作。

NewMyClass myC = new NewMyClass();
List<MyClass> myList = myC.method();

foreach(MyClass a in myList){
    Console.WriteLine(a.property);
} 

正如您所希望的那样,我希望让他们将它用作数据类型,因为它将是它所需要的列表类型。但我不希望用户在Name中设置MyClass,也无法致电new MyClass。我尝试将MyClass放入界面,但我需要创建新实例以存储在List内。

我还尝试设置private set,以便只有NewMyClass可以设置它们,但这也不起作用。我已经阅读了一段时间了,我就这么卡住了!

我希望用户能够做什么〜!

List<MyClass> //use as a datatype
Console.WriteLine(a.property); //call the property from the list

我不希望用户做什么!

new MyClass();
a.property = "Other Name" //set the value.

原因

用户没有理由只调用MyClass NewMyClass应该调用它。此外,用户没有理由将值分配给MyClass中的任何属性。我正在使用一个类,因为我被告知不要使用struct这是好的,因为我喜欢到目前为止类方法的多功能性。但我需要从用户那里限制很多。

如果我错了,请告诉我,我对C#很陌生,所以请不要害怕告诉我你走哪条路,为什么我能理解你的推理

思考第二步

回到struct方法。我现在有

internal struct MyClass {
    public string Name {get; set;}
}

我喜欢这个是我做的时候

MyClass cls = new MyClass();

它会发出警告,表明cls已分配但从未使用过。但是当我们做的时候

cls.Name = "google";

这个警告消失了,这让我不想让用户设置,但只有我的主要课程才能做到。

4 个答案:

答案 0 :(得分:3)

您无法通过namespace限制访问权限。最接近您要查找的访问修饰符是internal,它将范围限制为给定的程序集。

如果您将MyClassNewMyClass放在同一个程序集中,并将MyClass构造函数的访问修饰符设置为internal,那么您将前往解。

参考:https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx

答案 1 :(得分:0)

你需要公开'MyClass',但它是'内部'成员。当然,“内部”仅在这些类位于单独的程序集中时才有效。

namespace MyNameSpace {

   public class MyClass {

       internal string Name { get; set; }
   }

   public class NewMyClass {
       MyClass cls = new MyClass();
       cls.Name = "My Name";
   } 
} 

答案 2 :(得分:0)

虽然很难将创建限制在一个不在继承链中的类型(由于缺少你需要的accessibility level),你可以使用嵌套类型做一些技巧。

class NewMyClass {

  private static Func<MyClass> create = null;

  public class MyClass {
    public static void Init() { NewMyClass.create = ()=> new MyClass();}
    private MyClass(){ }
    public string Name { get; set; }
  }

  public MyClass Method(){
    MyClass.Init(); 
    MyClass cls = create();
    cls.Name = "My Name";
    return cls;
  }
} 
private的{​​{1}}构造函数阻止任何人直接创建。

static helper MyClass允许其外部类初始化私有委托来创建实例。嵌套类可以设置外部类的私有委托 - 因此两者都必须合作以允许您想要的保护。

请注意,更合理的方法是让MyClass.Init()成为抽象(或接口)并在MyClass内提供private实现 - 您可能会发现这种方法也更容易测试。< / p>

答案 3 :(得分:0)

如果你可以在单独的大会上将其分开,因为格伦已经指出它将是最好的。 然后你需要一个接口&amp;工厂方法。

此外,我尝试更改您的程序,因此它使用接口 -

    namespace MyNameSpace {



       public interface IMyClass
        {
            string Name { get; }
        }

       internal class MyClass : IMyClass  {

          public string Name { get; internal set; }
       }

       class NewMyClass {


           private IMyClass Init(string name)
           {
               MyClass cls = new MyClass();
               cls.Name = name;
               return cls;
           }

         public List<IMyClass> method()
           {
              var collection = new List<IMyClass>();

              collection.Add(Init("1st Sample"));
              collection.Add(Init("2nd Sample"));

              return collection;
           }

       } 
    }

    namespace UserNameSpace
    {

        public class Prog
        {
            public static void Func()
            {

                NewMyClass myC = new NewMyClass();
                List<IMyClass> myList = myC.method();

                foreach (IMyClass a in myList)
                {
                    Console.WriteLine(a.Name);
                }
            }
        }
    }

但是,如果两个命名空间都在同一个程序集中,那么用户无论如何都能够实例化该类。