Reputation: 877
Suppose I have a class Student and it contains a private member StudentID. Now I make an object of Student class in some another class and my requirement is to to change the value of StudentID. Is it possible to access StudentID and change its value?
Upvotes: 0
Views: 1810
Reputation: 6220
In short: No.
In Long: Depends.
You can expose the private field via a property
private int _studentID;
public int StudentID
{
get { return _studentID; }
set { _studentID = value; }
}
But somehow I don't think that's what you're after.
Private fields are private for a reason if you don't want it to be private then don't have it private, or expose it via a property as shown above.
If you really need to access a private field and set its value then you can take the reflection route:
var a = new abc();
a.GetType().GetField("x",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(a, 12);
You get the type then pull out the field using the Instance and NonPublic fields then just set the value.
SO:
public sealed class SomeClass
{
private int _studentID = 0;
public int StudentID
{
get
{
return _studentID;
}
set
{
_studentID = value;
}
}
}
Would be the "right" way, but using reflection you could just do
var someclass = new SomeClass();
someclass.GetType()
.GetField("_studentID",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.SetValue(someclass, 12);
If you want to use reflection then you could use an extension method helper:
public static class FieldExtensions
{
public static void SetPrivateField<T>(this T instance, string field, object value)
{
typeof(T).GetField(field, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(instance, value);
}
}
Then using that extension method you can set any private field on any object!
var someclass = new SomeClass();
someclass.SetPrivateField("_studentID", 12);
Upvotes: 2
Reputation: 700800
You could use reflection to change the private member, but that's probably not what you are looking for.
If you don't want to make the member public, you can make a public method that changes it:
public class Student {
private int StudentID;
public void SetStudentId(int id) {
StudentID = id;
}
}
If you don't want the public method easily accessible, you can make an interface for it, and implement the interface specifically. That way the method is only available when you have a reference of the type of the interface, not when you have a reference of the type of the class:
public interface IChangeId {
public void SetStudentId(int id);
}
public class Student : IChangeId {
private int StudentID;
void IChangeId.SetStudentId(int id) {
StudentID = id;
}
}
Example:
Student john = new Student();
john.SetStudentId(42); // not allowed
IChangeId johnSetId = john;
johnSetId.SetStudentId(42); // allowed
Upvotes: 1
Reputation: 40990
You can make Public
property of Student
class which access the value of private member _StudentId
public class Student
{
private int _StudentId;
public int StudentId
{
get
{
return _StudentId;
}
set
{
_StudentId = value;
}
}
}
Now you can use it like this
Student objStudent = new Student();
objStudent.StudentId = 5; // your Id
Upvotes: 1
Reputation: 34549
You could change it in a number of ways... you could make it a Public
property instead or you could use reflection to change it.
In reality, what if your code were to change the StudentID and now it conflicts with another Student? If you were to create a class that controls the students for example a StudentCollection
this class could then have a ChangeId
like the following:
public class StudentCollection : List<Student>
{
public void ChangeId(Student student, int newId)
{
if(students.Where(s => s.Id == newId).Count() > 0)
throw new ArgumentException("A student already has that Id");
student.Id = newId;
}
}
You could at that point make the Id internal, or use methods to try and reduce the chance of someone directly modifying it directly.
Upvotes: 0
Reputation: 121
You may use Reflection in this case:
FieldInfo StudentIDField= typeof(Student).GetField("StudentId",BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
StudentIDField.SetValue(1);
Upvotes: 0
Reputation: 813
You need to encapsulate it in a public method. Easiest way (if you're using Visual Studio Pro or above) is to right-click the property where it is declared, move over "Refactor" and click "Encapsulate field". VS automatically makes get and set modifiers. You may remove eiter in order to make the property read-only or write-only.
If the property is declared as "int studentId", the resulting encapsulation will be at "Student.StudentId" (notice the capital letter). If the property is declared as "int StudentId", the encapsulation will default to "Student.StudentId_1" as far as I remember. You may choose your own name during creation.
If you're using Visual Studio Express or another editor, just do this:
public int StudentId() { return this.studentId; }
Upvotes: 0
Reputation: 45119
The clean way would be to make it a public property or at least provide a public method to change the id.
public StudentID {get; set;}
// or
public StudentID {get; private set;}
public ChangeStudentID(int newID);
The dirty way would be reflection:
var instance = new Student();
var type = instance.GetType();
var propInfo = type.GetProperty("StudentID", BindingFlags.Instance | BindingFlags.NonPublic);
propInfo.SetValue(instance, 14, null);
Upvotes: 0
Reputation: 819
You could make it public:
public int StudentId {get;set;}
Alternatively, you can make a separate method to change it:
private int StudentId;
public void ChangeStudentId(int NewStudentId)
{
StudentId = NewStudentId;
}
Upvotes: 0
Reputation: 1659
Perhaps it make sense to pass ID value in a constructor, so I would add another constructor accepting some value for StudentID
.
Upvotes: 0
Reputation: 760
No you can't. You need to either have a public property that accesses student ID private member or you can access it using some public methods.
Upvotes: 0