This way of using struct puzzled me - c#

As I know before using a struct , I must have a object of it. Then I can't understand the following codes. Maybe the problem is somewhere else I can't find. Please help me.
namespace Ixxat.Vci3.Bal.Can
{
public struct CanBitrate
{
.....
public static CanBitrate Cia10KBit { get; }
public static CanBitrate Cia125KBit { get; }
public static CanBitrate Cia20KBit { get; }
public static CanBitrate Cia250KBit { get; }
public static CanBitrate Cia500KBit { get; }
public static CanBitrate Cia50KBit { get; }
public static CanBitrate Cia800KBit { get; }
// Gets an array of all available CiA baud rates.
public static CanBitrate[] CiaBitRates { get; }
// Gets a empty bit timing value.
public static CanBitrate Empty { get; }
public string Name { get; }
public override sealed string ToString();
}
}
Abrove all is the given interface, I think the "Cia125KBit" is a function of the struct. Then in another file, there is a function like this:
mCanCtl.InitLine( CanOperatingModes.Standard | CanOperatingModes.ErrFrame
, CanBitrate.Cia125KBit);
the definition of the InitLine is as follows:
public interface ICanControl : ICanSocket
{
...
void InitLine(CanOperatingModes operatingMode, CanBitrate bitrate);
}
My question is , CanBitrate is the name of struct, why it can be used in the function like CanBitrate.Cia125KBit? As I learned, It should like this
CanBitrate a;
a.Can125KBit;
I think there must something I am unknown or misunderstand . Ask for help.

Cia125KBit is a static member which means that it can be accessed without creating an instance of the struct. As MSDN puts it,
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.
To contrast this, the member Name is not declared as static. Therefore, trying to do something like CanBitRate.Name would throw an error.

The thing you're missing is the keyword static. A method, property or field of a class can be declared static to decouple it from individual instances, meaning that it's accessed through the class itself as opposed to objects.

It's because Cia125KBit is a static member. Static members are not bound to any instance and can be accessed only via class/struct name.

Related

How to restrict access to a nested class to its container in C#?

I have a configuration class store application configuration. Currently I am using a static class. Some of the configurations are related to one topic so I want to organize them into a nested class, so I can reference configurations like this:
AppConfig.Url
AppConfig.LogSettings.FileSize
I have two options, either use a static nested class,
public static class AppConfig
{
public static class LogSettings
{
public static int FileSize {get; set;}
}
}
or declare a class but add a static property:
public static class AppConfig
{
public class LogSettings
{
public int FileSize {get; set;}
}
public static LogSettings logSettings { get; private set; }
}
However, none of them can protect nested class member FileSize being modified by other classes, even I use private set to protect the public static property.
Maybe I should not use nested class to implement this? Any suggestions?
The other solutions given so far essentially require the property being set to be set once. I am very much in favour of immutable objects, but they are not always practical; is it possible to solve your problem and make the property mutable?
This is in fact a special case of the more general problem you pose: how can we mark certain members of an inner class as being accessible only to the outer class, but not to anything outside of that class?
It is by no means obvious how to do so, but this is surprisingly easy. The key to the solution is to remember that interfaces may be private implementation details. C# requires that a base class be at least as accessible as the class deriving from it, but C# does not require that an implemented interface be as accessible as the class implementing it!
using System;
public static class Outer
{
private interface IPrivates
{
string Name { set; }
}
public readonly static Inner TheInner = new Inner();
private readonly static IPrivates TheInnerPrivates = TheInner;
public class Inner : IPrivates
{
public string Name { get; private set; }
string IPrivates.Name { set { this.Name = value; } }
}
public static void DoIt()
{
TheInnerPrivates.Name = "abc";
}
}
public class Program
{
public static void Main()
{
Outer.DoIt();
Console.WriteLine(Outer.TheInner.Name);
}
}
Code inside of Outer may access the private members of Inner via the interface. Code outside of Outer cannot see anything other than the public members of Inner, because the interface they need to see the private members is itself private.
I voted for Eric's answer but wanted to put this here as 'something to consider'.
public class Tester
{
public Tester()
{
AppConfig.LogSettings.FileSize = 5; // compile error
Console.WriteLine(AppConfig.LogSettings.FileSize); // works
}
}
public static class AppConfig
{
// just an example of setting the value in the outer class
private static void SetFileSize(int size)
{
fileSize = size; // internal only setting works
}
private static int fileSize; // a member of AppConfig still
public static class LogSettings
{
public static int FileSize
{
get { return fileSize; } // internal classes can access private members of the outer class
}
}
}
When you access AppConfig externally you get the grouping you desire, however inside the AppConfig class the 'grouping' is simply about publicly exposing the getter, the actual member variable still belongs to AppConfig.
This works because the internal class can access private members of the outer class.
So if your grouping goal is mostly about the public interface - how you get the values - this approach is simpler, but if your goal is also have the grouping internally too...then obviously it doesn't deliver.
One option is to use a constructor of nested class to initialize values. For example:
public static class AppConfig {
static AppConfig() {
Log = new LogSettings(1);
}
public class LogSettings {
public LogSettings(int fileSize) {
FileSize = fileSize;
}
public int FileSize { get; private set; }
}
public static LogSettings Log { get; private set; }
}
Then other classes can create instance of LogSettings still, but cannot modify your instance.
If this is the approach you want to go with, I see 2 options:
You extract all the logic surrounding loading and parsing of the config file into a separate project (library), than you can mark your setters internal and other libraries won't be able to access them anymore.
You can implement a more explicit property which doesn't allow to set a value twice like:
private int? _fileSize;
public int FileSize {
get { return _fileSize ?? 0; }
set {
if (_fileSize.HasValue) {
throw new InvalidOperationException("You can only set the value once");
}
_fileSize = value;
}
}
Another option, which I've often used, is to encapsulate the parsing of different parts of a configuration to the sub classes. You provide that information in the constructor and the class initializes itself. (just like Evk commented in the meanwhile)

Static Type Mess

Static Type cant be used as type arguments
BUT
Extension Method should be in a Static class
I have a class piece so I can create List<piece> in my code
Now when I try to create an extension and ask me to create the class as static. But if I do that can't create List<piece>. So I'm in a recursive dilema here.
As you can see I'm trying to clone my piece.
public class piece
{
public int height { get; set; }
public int width { get; set; }
public int[] shape { get; set; }
public int quality { get; set; }
public int x { get; set; }
public int y { get; set; }
public static T CloneJson<T>(this T source)
{
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
}
}
So what is the proper way to handle this scenario?
I have my class working fine. I try to add clone functionality and found that extension method. That is when mess start, yes, I'm not really familiar with extension or instance method. I'm trying to make it work
My guess is create the extension as a method instead, but I don't know how to do that.
Two things you need to consider:
First: that method have no reason to be on that class. It does not represent any functionality of piece, as it is generic and can return any type.
Second: Extension methods should be on static class, yeah, but not on the same class where the type is defined. It must be defined on a static class and is consumed by other classes by referencing to that static class namespace.
So what you probably want to do is something like this:
namespace MyApp.MyExtensions
{
public static class CloneExtensions
{
public static T CloneJson<T>(this T source)
{
if (Object.ReferenceEquals(source, null))
return default(T);
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
}
}
}
Then you could use
namespace MyApp
{
using MyApp.Extensions;
public class TestClass
{
public TestClass()
{
var item = new piece();
var clone = piece.CloneJson();
}
}
}
That method would only make sense to be on the piece class if it was explicitly typed to clone only that piece class. In that case, it shouldn't be an extension method at all, but just an regular non-static method on that class.
If you need extension methods of the piece class, just throw the extension method into another class - PieceExtensions or such. This is done even in .NET for the IEnumerable Extension Methods.

C# new class clears base class values

I've searched extensively (though might have missed it). I've been doing so much web development that I can't seem to get this. I have a base case:
public class myfields
{
public String myfield1 { get; set; }
}
Then another class using this class:
class mydohere : myfields
{
public Boolean getValue {string xyz)
{
string abc = myfield1;
}
}
What I can't get it is, if I create:
mydohere Objmydohere = new mydohere();
The value of myfield1 is now null! All the values in base myfields are set to null (or empty since it is a new object). What is the best way to create fields (or parameters) in one class and share it among others without resetting their values? I've tried using keyword 'base'. I've tried using props and fields *since you can't instantiate them).
My goal is to to have a class of settable fields that I can use accross classes without making that class new for each class that is using it. Does this make sense? I'm sure there is a much better way to do this :)
It sounds like what you're looking for is a constant or static variable.
Use constant if it will always be the same:
const string myfield1 = "my const";
Use static if you'd like to set it once, maybe after doing some logic:
static string myfield1 = "my static";
This really depends on what you want to do with this "shared data" One way is to use a static class and dependency injection:
public interface Imyfields
{
String myfield1 { get; set; }
}
public class myfields : Imyfields
{
private static readonly Imyfields instance = new myfields();
private myfields()
{
}
public static Imyfields Instance
{
get
{
return instance;
}
}
public String myfield1 { get; set; }
}
class mydohere
{
private readonly Imyfields myfields;
public mydohere(Imyfields myfields)
{
this.myfields = myfields;
}
public Boolean getValue(string xyz)
{
string abc = this.myfields.myfield1;
}
}
Nothing is reset to null, it's never initialized with a value in the first time. In your base object, you only have a getter/setter, you don't have any code that initialize the value itself.
Maybe I don't understand the question well and others suggestion with static are what you really need! :)

typedef emulation in C#

I have a field variable named uid in a class. The type is int, but I want to open the possibility that I change it long or short.
With C++, typedef is the one for this purpose, but I see C# doesn't have typedef.
Is there a way to mimic typedef in C#?
I think you're trying to alias the type. If so, you can alias it via the using alias directive. You must specify the fully qualified type (the entire namespace) when assigning an alias.
For example:
using System;
using MyAlias = System.Int32;
namespace UsingAlias
{
class Program
{
static void Main(string[] args)
{
MyAlias temp = Math.Min(10, 5);
Console.WriteLine(temp);
MyAlias result = MyAlias.Parse("42");
Console.WriteLine(result);
}
}
}
Try making a class. It's like a typedef on steroids, and you can change the internal representation as much as you want without affecting the interface!
You could even make it a guid!
Make it a struct:
struct Uid { public int Value; }
Encapsulate it in it's own class (or a struct, if more appropriate).
public class UID
{
public int Value { get; set; }
}
Write your methods in terms of your UID class, limiting the exposure to the actual value type to the smallest subset of code necessary.
publc class Entity
{
public UID ID { get; set; }
public void Foo( UID otherID )
{
if (otherID.Value == this.ID.Value)
{
...
}
}
}
}
Define a struct with just one field
public struct ID_Type
{
public long Id;
};
and use it whereever you need it.
If you have just one class where the ID type is needed, you can also try to make this class a generic class with the UID type being a type parameter.
You could always use generics:
public class Foo<T>
{
public T MyField { get; set; }
}
public class FooInt : Foo<int>
{
}
public class FooShort : Foo<short>
{
}
or, just change it later on.
/// want an int
public class Foo
{
public int MyField { get; set; }
}
/// and just change it later on:
public class Foo
{
public short MyField { get; set; }
}
Wouldn't the result be the same if you used int and then changed it later on?
See this , he uses Operator Overloading
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/019a258e-8d50-4a9f-b0ef-8311208ebb6a/
Here is a simple solution that helped.
using typedef = System.Int32;
class MyTypeDef
{
typedef ERROR, TRUE=1, FALSE=0;
public int MyMethod()
{
if(this is an error condition)
{
ERROR = TRUE;
}
else
{
ERROR = FALSE;
}
return ERROR;
} // end MyMethod
} // end MyTypeDef
Is there a way to mimic typedef in C#
No
to solve my problem
What problem?

C# Automatic Properties - Why Do I Have To Write "get; set;"?

If both get and set are compulsory in C# automatic properties, why do I have to bother specifying "get; set;" at all?
Because you might want a read-only property:
public int Foo { get; private set; }
Or Write-only property:
public int Foo { private get; set; }
ERROR: A property or indexer may not be passed as an out or ref parameter
If you didn't specify {get; set;} then the compiler wouldn't know if it's a field or a property.
This is important becasue while they "look" identical the compiler treats them differently. e.g. Calling "InitAnInt" on the property raises an error.
class Test
{
public int n;
public int i { get; set; }
public void InitAnInt(out int p)
{
p = 100;
}
public Test()
{
InitAnInt(out n); // This is OK
InitAnInt(out i); // ERROR: A property or indexer may not be passed
// as an out or ref parameter
}
}
You shouldn't create public fields/Variables on classes, you never know when you'll want to change it to have get & set accessors, and then you don't know what code you're going to break, especially if you have clients that program against your API.
Also you can have different access modifiers for the get & set, e.g. {get; private set;} makes the get public and the the set private to the declaring class.
Just thought I would share my findings on this topic.
Coding a property like the following, is a .net 3.0 shortcut call “auto-implemented property”.
public int MyProperty { get; set; }
This saves you some typing. The long way to declare a property is like this:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
When you use the “auto-implemented property” the compiler generates the code to wire up the get and set to some “k_BackingField”. Below is the disassembled code using Reflector.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
[CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
disassembled C# code from IL
Also wires up a method for the setter and getter.
[CompilerGenerated]
public void set_MyProperty(int value)
{
this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
return this.<MyProperty>k__BackingField;
}
disassembled C# code from IL
When you declare a read only auto-implemented property, by setting the setter to private:
public int MyProperty { get; private set; }
All the compiler does flag the "set" as private. The setter and getter method say the same.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
private [CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
disassembled C# code from IL
So I am not sure why the framework require both the get; and set; on an auto-implemented property. They could have just not written the set and setter method if it was not supplied. But there may be some compiler level issue that makes this difficult, I don't know.
If you look at the long way of declaring a read only property:
public int myProperty = 0;
public int MyProperty
{
get { return myProperty; }
}
And then look at the disassembled code. The setter is not there at all.
public int Test2
{
get
{
return this._test;
}
}
public int get_Test2()
{
return this._test;
}
disassembled C# code from IL
Because you need some way to distinguish it from plain fields.
It's also useful to have different access modifiers, e.g.
public int MyProperty { get; private set; }
The compiler needs to know if you want it to generate a getter and/or a setter, or perhaps are declaring a field.
If the property didn't have accessors, how would the compiler separate it from a field? And what would separate it from a field?
Well, obviously you need a way of disambiguating between fields and properties. But are required keywords really necessary? For instance, it's clear that these two declarations are different:
public int Foo;
public int Bar { }
That could work. That is, it's a syntax that a compiler could conceivably make sense of.
But then you get to a situation where an empty block has semantic meaning. That seems precarious.
Since no one mentioned it... you could make the auto-property virtual and override it:
public virtual int Property { get; set; }
If there was no get/set, how would it be overridden? Note that you are allowed to override the getter and not the setter:
public override int Property { get { return int.MinValue; } }
Also, because ever since C# 6.0 (in Visual Studio 2015, at the time of this answer available in version Ultimate Preview) you may implement a true read-only property:
public string Name { get; }
public string Name { get; } = "This won't change even internally";
... as opposed to currently imperfect workaround with public getter/private setter pair:
public string Name { get; private set; }
public Constructor() { Name="As initialised"; }
public void Method() { Name="This might be changed internally. By mistake. Or not."; }
Example of the above below (compiled and executable online here).
using System;
public class Propertier {
public string ReadOnlyPlease { get; private set; }
public Propertier() { ReadOnlyPlease="As initialised"; }
public void Method() { ReadOnlyPlease="This might be changed internally"; }
public override string ToString() { return String.Format("[{0}]",ReadOnlyPlease); }
}
public class Program {
static void Main() {
Propertier p=new Propertier();
Console.WriteLine(p);
// p.ReadOnlyPlease="Changing externally!";
// Console.WriteLine(p);
// error CS0272: The property or indexer `Propertier.ReadOnlyPlease' cannot be used in this context because the set accessor is inaccessible
// That's good and intended.
// But...
p.Method();
Console.WriteLine(p);
}
}
Other tasty news about C# 6.0 available as official preview video here.

Categories

Resources