Do you use the "this" operator in C#? [duplicate] - c#

This question already has answers here:
Closed 14 years ago.
Duplicate post, see: When do you use the "this" keyword?
On almost every project I worked the "This" operator is used, when i start developing i was told that it is a good practice. is this really necessary does it gives you more readability?

Tools like Resharper have a built in hint saying "redundant qualifier," but I disagree with it and quickly disable the rule.
I always use the this qualifier because it lets me know at a glance whether or not the reference is a property/field, or a static class ref for example:
public class MyClass {
public int Foo { get; set; }
}
public MyClass MyRef { get; }
or
public static class MyRef {
public static int Foo { get; set; }
}
so:
void method() {
MyRef.Foo = 4; // might be either
}
void method() {
this.MyRef.Foo = 4; // definitely property/field
}
Just my 2c.
-Oisin

Related

Easy way to share private variables with constructed class in C#

So I'm aware of several ways to make private fields accessible to other classes, I just I feel like their must be an easier way because I could do it easier in C++ with pointers.
Basically, I have a class with a large number of integers, that then creates a number of classes that use these integers. But each class only uses a few integers each. What I want is to allow each class to access only the variables that they need, but have all the remaining integers be unaccessible.
Basically what I would do in C++ is:
class PrivateClass
{
private:
int a, b, c, d;
public:
void DoStuff();
};
And then
void DoStuff()
{
ClassOne class_one(&a, &b);
ClassTwo class_two(&c, &d);
//stuff
}
So then class_one has access to the values of a and b, while class_two has access to the values of c and d. (Also, if I've made any errors in my code forgive me, it has been a while since I've actually written in C++)
Given how easy it is to do there, it makes me feel (perhaps erroneously) like there must be a similarly easy method in C#. If not, I'll mostly just make an indexer to encapsulate the variables so that they can be accessed that way.
Edit: Basically I'm getting that I should just use properties like I've been weirdly avoiding. I don't mind making properties for a few fields, but for some reason doing it for 30 or so just feels wrong, like there should be a better way.
The idea of sharing private variables with another class doesn't quite make sense. There are various access modifiers, but that doesn't help if you want one class to have access to certain members, another class to have access to different members, and so forth.
So the first question is how to share variables. Typically we do that with properties.
In this example another class can read A but can't change it. Another class can both read and write B. There is no property for changing _c.
If we want to split hairs, nothing outside the class can actually read or change the variables. They can only access the property, and the property reads/writes the variable.
(You can also do this with auto-properties. You don't need a variable and a separate property. But that's irrelevant for now.)
class PrivateClass
{
private int _a;
private int _b;
private int _c;
public int A => _a;
public int B
{
get { return _b; }
set { _b = value; }
}
};
Next you want to be able to control which classes can "see" which variables.
As long as there are properties, you can't absolutely prevent someone from writing code that calls them. But you can control how one class "sees" another class.
Here's a contrived example. These types don't make much sense.
public class PublicTransportVehicle : IPublicTransport, IMotorVehicle
{
public int PassengerCapacity { get; private set; }
public int PassengerCount { get; set; }
public int AxleCount { get; private set; }
}
public interface IPublicTransport
{
int PassengerCapacity { get; }
int PassengerCount { get; set; }
}
public interface IMotorVehicle
{
int AxleCount { get; }
}
The PublicTransportVehicle class has three int properties. Two are read-only. One is read-write. (I used auto-properties instead of variables. This just means that if set is private then only the class itself can set the property.)
Now I can write a class with a method that takes an argument of type IPublicTransport. I can pass an instance of PublicTransportVehicle or any other class that implements the interface. But the method only sees IPublicTransport. The only properties it knows about are the ones exposed by that interface.
I can write another method that takes an argument of type IMotorVehicle and it only interacts with the properties defined in that interface.
I can pass an instance of PublicTransportVehicle to either method because it implements both interfaces, but each one sees it differently.
Can we absolutely prevent the caller from accessing properties we didn't want it to access? That's a lot harder. For example, a class could do this:
public void DoSomethingWithMotorVehicle(IMotorVehicle motorVehicle)
{
var publicTransportVehicle = motorVehicle as PublicTransportVehicle;
if (publicTransportVehicle != null)
{
publicTransportVehicle.PassengerCount = 1000;
}
}
But we usually can't and shouldn't bother trying to exercise complete control over that. It's practically impossible. The idea is to communicate which properties and methods consumers are expected to interact with. We do that by deliberately making them accessible. If someone wants to something weird like casting an object or using reflection there's not a lot we can do. Unless it's a serious security-related matter we don't need to worry about that.
Private fields, methods, properties, constructors, and events are all meant to be used by the class only. If you want to access these fields from other classes, you can make something like this:
using System;
namespace SharePrivateFields
{
class Supervisor
{
void DoStuff()
{
var subject = new Subject();
var first = new First(subject);
var second = new Second(subject);
}
}
class Subject : IFirstSubject, ISecondSubject
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
interface IFirstSubject
{
int A { get; set; }
int B { get; set; }
}
interface ISecondSubject
{
int C { get; set; }
int D { get; set; }
}
class First
{
private IFirstSubject _subject;
public First(IFirstSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // Completely correct
Console.WriteLine(_subject.C); // `IFirstSubject` does not contain definition for `C`
}
}
class Second
{
private ISecondSubject _subject;
public Second(ISecondSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // `ISecondSubject` does not contain definition for `A`
Console.WriteLine(_subject.C); // Completely correct
}
}
}
However, we're now treading waters of Abstract Factory Design Pattern, which is a more desirable approach in this case.
I'm convinced that the C++ implementation you're mentioning is a flawed design, so it's a reason why you can't make it easy in C# (if we're being completely honest - you can, read about Unsafe code, pointer types, and function pointers; but it's 99% of a time taboo for C# code).
So I suggest you learn about Abstract Factory or at least use my solution for your use-case.
Make the method static and send the corresponding instance to it, then you can access the data you want.
Static Void DoStuff(PrivateClass instance)
{
ClassOne class_one(instance.a, instance.b);
ClassTwo class_two(instance.c, instance.d);
//stuff
}
But the reality is that it is wrong, you should either add reading and writing properties to your variables to be able to send them to DoStuff from outside as a parameter.
//in Main
PrivateClass pClass = new PrivateClass(1,30,2,19);
DoStuff(pClass.A, pClass.B, pClass.C, pclass.D);
//in PrivateClass
namespace Test
{
class PrivateClass
{
private int a;
private int b;
private int c;
private int d;
public PrivateClass(int a, int b, int c, int d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
public int A
{
get
{
return this.a;
}
set
{
this.a = value;
}
}//etc
public static void DoStuff(int a, int b, int c, int d)
{
ClassOne class_one(a, b);
ClassTwo class_two(c, d);
//stuff
}
}
}

Interface With Class Enums [duplicate]

This question already has answers here:
Enum "Inheritance"
(17 answers)
Closed 7 years ago.
Is there a way to interface with or inherit the enum of another class? Obviously I can move the enum outside of the class, but I am curious if a reference can be made:
public class deferment
{
public enum test
{
test = 0,
live
}
}
public class defermentLog
{
public enum test1 : deferment:test //this is where I want to reference
{
}
public test1 action()
{
return test1.live;
}
}
In that case, yes, you can.
namespace ConsoleTests
{
using TestAlias = Class1.test;
public class Class1
{
public enum test
{
test,
live
}
}
public class Class2
{
public void x()
{
TestAlias t = TestAlias.live;
}
}
}
Its called a type alias, and its defined like this: using TestAlias= Class1.test;
It should be noted though that you have to define that alias in the file that you use it and it does not copy over to other files, so you have to define it in every one you use it.

Something weird seems to have happened with C# classes

I used to be able to do this:
public class Something
{
public class SomethingElse
{
public static class ThisThing
{
public static string aoidj {get;set;}
}
}
}
But it no longer works.
My desired result (and what I've always been able to do) is:
Something.SomethingElse somethingElse = new Something.SomethingElse();
somethingElse.ThisThing.aoidj = "yay";
Console.WriteLine(somethingElse.ThisThing.aoidj);
But that no longer works. Instead of being able to access ThisThing from somethingElse, it's now appearing in SomethingElse.!
Has the C# language changed or something? The behaviour is definitely different and I don't know when it changed.
You need to do this:
Something.SomethingElse.ThisThing.aoidj = "yay";
Console.WriteLine(Something.SomethingElse.ThisThing.aoidj);
Or otherwise change your code to this:
public class Something
{
public class SomethingElse
{
public Whatever ThisThing = new Whatever();
public class Whatever
{
public string aoidj {get;set;}
}
}
}
And then you could do this (your desired result):
Something.SomethingElse somethingElse = new Something.SomethingElse();
somethingElse.ThisThing.aoidj = "yay";
Console.WriteLine(somethingElse.ThisThing.aoidj);
It has to appear in the SomethingElse., otherwise, how can you acces it, it is a Nested Type!
C# has not changed in this way. Nested Types have always been accessible through their parent types.
See my answer here: Cannot access nested classes or members of base class.
Besides, there is no point in having static classes as a Nested Type, since static classes are more commonly used as managers or providers, so they are mainly used elsewhere in your system.
Aside, if you want to access your static class members, you have to type in its name and access it once and for all.
Something.SomethingElse.ThisThing.aoidj
But I can't do that. It would be bad. I need to do it from somethingElse. Not SomethingElse.
Than make it a property rather than a class.
public class Something {
public class SomethingElse {
public OrEventSomethingElse ThisThing { get; set; }
}
}
public class OrEventSomethingElse {
public string aoidj { get; set; }
}
This way, you shall not be able to access it through your Nested Type SomethingElse, but rather through only an instance.
Some resources to help you understand OOP.
Object-Oriented Programming (C# and Visual Basic)
C# Tutorial - An Object Oriented Approach to Programming
Introduction to C# classes
C#.Net Tutorial 17-1 - Classes and Object-Oriented Programming (Part 1)
.NET Tutorial : Object Oriented Programming Using C# For Beginners - Part 1 - Introduction
Beginning C# Object-Oriented Programming
Object Oriented Programming using C# (DOWNLOAD FREE)
** I need it to be a class though, because there is more stuff to go inside of ThisThing**
Make it a class outside of SomethingElse so that you may access it as a simple instance member/property.
public class ThisThing {
public string Stuff { get; set; }
public int SomeMoreStuff { get; set; }
public DateTime EvenMoreStuff { get; set; }
// ...
public string ThisClassIsGettingHuge {
get {
return "Time to refactor because big classes tend to break SRP";
}
}
}
public class Something {
public class SomethingElse {
public ThisThing ThisThingAsAProperty { get; set; }
}
}
It is then, and only then that you shall only be able to access your instance.
var somethingElse = new Something.SomethingElse;
Console.WriteLine(somethingElse.ThisThingAsAProperty.ThisClassIsGettingHuge);
I have developed information and process for years, and I rarely use Nested Types. They generally cause more damage than they help.
Nothing is changed, but your code is wrong. And luckily I found answer too.
class Something
{
public class SomethingElse
{
public SomethingElse()
{
}
public static class sm
{
public static void set()
{
}
}
}
}
Use the class in this manner-
Something.SomethingElse.sm.set();

Initialize string properties to String.Empty [duplicate]

This question already has answers here:
What is the best way to give a C# auto-property an initial value?
(23 answers)
Closed 8 years ago.
I'm used to writing classes like this:
public class foo {
private string mBar = "bar";
public string Bar {
get { return mBar; }
set { mBar = value; }
}
//... other methods, no constructor ...
}
Converting Bar to an auto-property seems convenient and concise, but how can I retain the initialization without adding a constructor and putting the initialization in there?
public class foo2theRevengeOfFoo {
//private string mBar = "bar";
public string Bar { get; set; }
//... other methods, no constructor ...
//behavior has changed.
}
You could see that adding a constructor isn't inline with the effort savings I'm supposed to be getting from auto-properties.
Something like this would make more sense to me:
public string Bar { get; set; } = "bar";
Update - the answer below was written before C# 6 came along. In C# 6 you can write:
public class Foo
{
public string Bar { get; set; } = "bar";
}
You can also write read-only automatically-implemented properties, which are only writable in the constructor (but can also be given a default initial value):
public class Foo
{
public string Bar { get; }
public Foo(string bar)
{
Bar = bar;
}
}
It's unfortunate that there's no way of doing this right now. You have to set the value in the constructor. (Using constructor chaining can help to avoid duplication.)
Automatically implemented properties are handy right now, but could certainly be nicer. I don't find myself wanting this sort of initialization as often as a read-only automatically implemented property which could only be set in the constructor and would be backed by a read-only field.
This hasn't happened up until and including C# 5, but is being planned for C# 6 - both in terms of allowing initialization at the point of declaration, and allowing for read-only automatically implemented properties to be initialized in a constructor body.
You can do it via the constructor of your class:
public class foo {
public foo(){
Bar = "bar";
}
public string Bar {get;set;}
}
If you've got another constructor (ie, one that takes paramters) or a bunch of constructors you can always have this (called constructor chaining):
public class foo {
private foo(){
Bar = "bar";
Baz = "baz";
}
public foo(int something) : this(){
//do specialized initialization here
Baz = string.Format("{0}Baz", something);
}
public string Bar {get; set;}
public string Baz {get; set;}
}
If you always chain a call to the default constructor you can have all default property initialization set there. When chaining, the chained constructor will be called before the calling constructor so that your more specialized constructors will be able to set different defaults as applicable.
This will be possible in C# 6.0:
public int Y { get; } = 2;
In the default constructor (and any non-default ones if you have any too of course):
public foo() {
Bar = "bar";
}
This is no less performant that your original code I believe, since this is what happens behind the scenes anyway.

To "this" or not to "this" in C#? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicates:
When do you use the “this” keyword?
Best practices for using the ‘this’ keyword in C#
I have a style question regarding the this keyword. Do you use this when self-referencing auto-implemented properties or methods within a class for the sake of clarity?
For one example, in your Constructor, do you write your parameter assignments as:
public class Foo
{
public string FooProperty { get; set; }
public Foo(string fooProperty)
{
this.FooProperty = fooProperty;
}
...
}
OR as:
public class Foo
{
public string FooProperty { get; set; }
public Foo(string fooProperty)
{
FooProperty = fooProperty;
}
...
}
IMHO, the this is a very useful keyword. Once I see the "this", I know it is a class variable. Otherwise, I would have to check whether its a parameter, a variable declared within the method. "This" saves time :) (ambiguous joke hehe)

Categories

Resources