J'ai une classe .Net C # où j'ai besoin de rendre une variable publique. J'ai besoin d'initialiser cette variable dans une méthode (pas dans le constructeur). Cependant, je ne veux pas que la variable soit modifiable par d'autres classes. Est-ce possible?
Ne pas utiliser un champ - utiliser une propriété:
class Foo
{
public string Bar { get; private set; }
}
Dans cet exemple, Foo.Bar
est lisible partout et ne peut être écrit que par les membres de Foo
lui-même.
Remarque: cet exemple utilise une fonctionnalité C # introduite dans la version 3, appelée propriétés automatiquement implémentées . C'est le sucre syntaxique que le compilateur transformera en une propriété standard qui possède un champ de sauvegarde privé comme celui-ci:
class Foo
{
[CompilerGenerated]
private string <Bar>k__BackingField;
public string Bar
{
[CompilerGenerated]
get
{
return this.<Bar>k__BackingField;
}
[CompilerGenerated]
private set
{
this.<Bar>k__BackingField = value;
}
}
}
public class Foo
{
public string Bar { get; private set; }
}
Vous devez utiliser une propriété pour cela. Si vous êtes d'accord avec une implémentation automatique du getter/setter, cela fonctionnera:
public string SomeProperty { get; private set; }
Notez que vous ne devez de toute façon pas exposer les champs comme publics, sauf dans certaines circonstances limitées. Utilisez plutôt une propriété.
Sûr. Faites-en une propriété et rendez le setter privé:
public Int32 SomeVariable { get; private set; }
Ensuite, pour le définir (depuis une méthode de la classe):
SomeVariable = 5;
Utilisez une variable privée et exposez une propriété publique.
class Person
{
private string name;
public string Name
{
get
{
return name;
}
}
}
Vous n'êtes pas autorisé à utiliser une propriété pour cela? Si vous êtes:
private string _variable
public string Variable {
get {
return _variable;
}
}
Necro bien sûr, mais cela mérite d'être mentionné avec les améliorations apportées au langage dans la version 6.0
class Foo {
// The new assignment constructor is wonderful shorthand ensuring
// that the var is only writable inside the obj's constructor
public string Bar { get; } = String.Empty;
}
Jusqu'ici, les réponses fonctionnent bien tant que vous n'utilisez pas de types de référence. Sinon, vous pourrez toujours manipuler les éléments internes de cette variable. Par exemple:
using System;
namespace Playground
{
class Program
{
static void Main(string[] args)
{
var fo = new Fo();
fo.Init();
Console.WriteLine(fo.SomeBar.SomeValue);
fo.SomeBar.SomeValue = "Changed it!";
Console.WriteLine(fo.SomeBar.SomeValue);
Console.Read();
}
public class Fo
{
public Bar SomeBar { get; private set; }
public void Init()
{
SomeBar = new Bar{SomeValue = "Hello World!"};
}
}
public class Bar
{
public String SomeValue { get; set; }
}
}
}
Ceci produira la sortie de la console:Hello World!
Changed it!
Ce qui peut être exactement ce que vous voulez car vous ne pourrez pas changer SomeBar mais si vous voulez rendre les éléments internes de la variable non modifiables, vous devez renvoyer une copie de la variable, par exemple :
using System;
namespace Playground
{
class Program
{
static void Main(string[] args)
{
var fo = new Fo();
fo.Init();
Console.WriteLine(fo.SomeBar.SomeValue);
fo.SomeBar.SomeValue = "Changed it!";
Console.WriteLine(fo.SomeBar.SomeValue);
Console.Read();
}
public class Fo
{
private Bar _someHiddenBar;
public Bar SomeBar => new Bar(_someHiddenBar);
public void Init()
{
_someHiddenBar = new Bar{SomeValue = "Hello World!"};
}
}
public class Bar
{
public String SomeValue { get; set; }
public Bar(){}
public Bar(Bar previousBar)
{
SomeValue = previousBar.SomeValue;
}
}
}
}
qui aura pour résultat la sortie:Hello World!
Hello World!
Voir les commentaires pour savoir pourquoi j'ai ajouté le troisième exemple:
using System;
namespace Playground
{
class Program
{
static void Main(string[] args)
{
var fo = new Fo();
fo.Init();
Console.WriteLine(fo.SomeBar.SomeValue);
//compile error
fo.SomeBar.SomeValue = "Changed it!";
Console.WriteLine(fo.SomeBar.SomeValue);
Console.Read();
}
public class Fo
{
private Bar _someHiddenBar;
public Bar SomeBar => new Bar(_someHiddenBar);
public void Init()
{
_someHiddenBar = new Bar("Hello World!");
}
}
public class Bar
{
public String SomeValue { get; }
public Bar(string someValue)
{
SomeValue = someValue;
}
public Bar(Bar previousBar)
{
SomeValue = previousBar.SomeValue;
}
}
}
}