C# 一种类型如何访问另一种类型的私有setter';谁的财产?
我所需要的只是一种方法,使一个类的属性只能从另一个类(一种管理器类)中“设置” 这在c#中可能吗C# 一种类型如何访问另一种类型的私有setter';谁的财产?,c#,access-modifiers,C#,Access Modifiers,我所需要的只是一种方法,使一个类的属性只能从另一个类(一种管理器类)中“设置” 这在c#中可能吗 我的同事“可靠地”告诉我,我有一个设计缺陷,但我觉得我至少应该在承认失败之前询问社区 不,在C#中以任何干净的方式都不可能做到这一点。您可能有设计缺陷;-) 不,在C#中以任何干净的方式都不可能做到这一点。您可能有设计缺陷;-) 是否是设计缺陷取决于您想做什么。您可以使用System.Diagnostics中的StackTrace类来获取设置属性的类的类型,然后与您希望允许设置或属性的类型进行比较。
我的同事“可靠地”告诉我,我有一个设计缺陷,但我觉得我至少应该在承认失败之前询问社区 不,在C#中以任何干净的方式都不可能做到这一点。您可能有设计缺陷;-) 不,在C#中以任何干净的方式都不可能做到这一点。您可能有设计缺陷;-) 是否是设计缺陷取决于您想做什么。您可以使用System.Diagnostics中的StackTrace类来获取设置属性的类的类型,然后与您希望允许设置或属性的类型进行比较。但是,如果是设计缺陷,可能有更好的方法来执行类似操作(例如装箱)。您可以使用System.Diagnostics中的StackTrace类来获取设置属性的类的类型,然后与您希望允许设置或属性的类型进行比较。但是可能有更好的方法来执行类似的操作(例如装箱)您不能这样做,但是您可以从派生类访问属性的setter方法,因此可以使用继承。您所要做的就是放置受保护的访问修改器。如果您尝试这样做,您的同事是对的:)。您可以尝试这样做:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
请记住,属性的set方法只能从派生类访问。这样做是不可能的,但可以从派生类访问属性的setter方法,因此可以使用继承。您所要做的就是放置受保护的访问修改器。如果您尝试这样做,您的同事是对的:)。您可以尝试这样做:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
请记住,属性的set方法只能从派生类访问。您可以通过在“可设置类”中创建一个公共属性来实现这一点,该属性将从具有受保护属性的真实类继承。。。这样,只有继承类可以设置,而不是不继承的类。但缺点是您需要有一个继承类…您可以通过在“可设置类”中创建一个公共属性来实现这一点,该属性将继承具有受保护属性的真实类。。。这样,只有继承类可以设置,而不是不继承的类。但是缺点是您需要有一个继承类…,或者您可以在一个程序集中单独有这两个类,并将setter作为内部类。尽管如此,我还是会投票赞成设计缺陷,除非milot之前的回答(继承和保护)是有意义的。或者您可以将这两个类单独放在一个程序集中,并将setter作为内部的。尽管如此,我还是会投票赞成设计缺陷,除非milot之前的回答(继承和保护)有意义。您可以使用
internal
修饰符,该修饰符允许同一程序集中的所有类型访问数据(如果使用[InternalsVisibleTo],则指定程序集)
-但是没有:C#中没有与之相当的朋友
例如:
public string Foo {get; internal set;}
您可以使用internal
修饰符,该修饰符允许同一程序集中的所有类型访问数据(如果使用[InternalsVisibleTo]
,则可以访问指定的程序集)-但否:C#中没有friend
等效项
例如:
public string Foo {get; internal set;}
你有一个设计缺陷。另外,不要对数据隐藏心存疑虑。下面是3.5的方法:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
你有一个设计缺陷。另外,不要对数据隐藏心存疑虑。下面是3.5的方法:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
你可以做:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
这意味着您可以使用调用类中的“This”指针。我会质疑您试图实现的逻辑,但在不知道具体情况的情况下,我无法进一步给出建议。我要说的是:如果可以重构代码以使其更清晰,那么这样做通常是值得的
但这是相当混乱,当然不是傻瓜证明…你已经被警告了
交替地
您可以将具有属性(类a)的类的委托传递给Manager类(类B)。委托可以引用a中的私有函数,以允许B将该委托作为任何普通函数调用。这排除了a知道B以及a可能是在B之前创建的。同样,这是一个混乱且不易出错的问题!您可以执行以下操作:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
这意味着您可以使用调用类中的“This”指针。我会质疑您试图实现的逻辑,但在不知道具体情况的情况下,我无法进一步给出建议。我要说的是:如果可以重构代码以使其更清晰,那么这样做通常是值得的
但这是相当混乱,当然不是傻瓜证明…你已经被警告了
交替地
您可以将具有属性(类a)的类的委托传递给Manager类(类B)。委托可以引用a中的私有函数,以允许B将该委托作为任何普通函数调用。这排除了a知道B以及a可能是在B之前创建的。同样,这是一个混乱且不容易出错的问题!最好的方法是:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
//
///获取或设置foo
///Setter只能由SomeClass调用
///
公共对象Foo
{
获取{return foo;}
设置{foo=value;}
}
当您有一些复杂的访问或继承限制,并且强制执行这些限制要求代码太复杂时,有时候最好的方法就是正确地对其进行注释
但是请注意,如果此限制具有某些安全含义,则不能依赖此限制,因为您取决于将使用此代码的开发人员的善意。最好的方法是