我试图让一个类只允许在命名空间范围内使用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";
这个警告消失了,这让我不想让用户设置,但只有我的主要课程才能做到。
答案 0 :(得分:3)
您无法通过namespace
限制访问权限。最接近您要查找的访问修饰符是internal
,它将范围限制为给定的程序集。
如果您将MyClass
和NewMyClass
放在同一个程序集中,并将MyClass
构造函数的访问修饰符设置为internal
,那么您将前往解。
答案 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);
}
}
}
}
但是,如果两个命名空间都在同一个程序集中,那么用户无论如何都能够实例化该类。