I have this code in C# but I have a problem whit this code:
struct myStruct
{
public string sOne;
public string sTwo;
}
public static int ChangeStruct(out myStruct[] arrmyStruct)
{
arrmyStruct= new myStruct[256];
arrSNChildrenStruct[0].sOne= "";
arrSNChildrenStruct[0].sTwo= "";
return 0;
}
But when I build, I have this error:
Inconsistent accessibility: parameter type 'out ........ is less accessible than method .....
What's wrong?
Thanks
Make a public struct myStruct instead of internal struct. Or make ChangeStruct() private if you only use it locally.
This has nothing to do with it being an out parameter, or an array. You'd get the same error with:
public static void ChangeStruct(myStruct foo)
Your method is public, but your struct is internal (the default accessibility for any top-level type) or private if it's a nested type. That means that any caller external to your assembly should have access to the method... but can't possibly understand the method signature. C# doesn't allow you to declare methods which refer to types which can't be seen by all possible callers.
Options:
Make the method internal or private
Make the struct public
Other notes:
Your naming is very unconventional. Name your types according to their meaning, and make it PascalCased. Drop the "arr" prefix from your variable names.
Public fields are usually a bad idea, as are mutable structs.
Related
I'm learning C#,and now i'm trying to understand static members and constants.Which is the best way to declare a constant?
This way?
class Myclass
{
public const double G=9.8;
}
Or
class Myclass
{
private static double G{get;set;}
static MyClass()
{
G=9.8;
}
}
I've asked this question because,with the 2 ways i access the membre with the same code:
Console.WriteLine(Myclass.G);
constant:
Constant fields are defined at the time of declaration in the code
snippet, because once they are defined they can't be modified. By
default a constant is static, so you can't define them static from
your side.
It is also mandatory to assign a value to them at the time of
declaration otherwise it will give an error during compilation of the
program snippet. That's why it is also called a compile-time constant.
Explanation:
Consider ff. code:
void Sum(int j)
{
const int i = 9, k = 2;
const int A = i + k;
}
This will produce a result of 11, without showing any error since we already declared it at the initial point of declaration.
But how about:
void Sum(int j)
{
const int i = 9, k = 2;
//const int A = i + k;
Const int B = i + j;
}
This code snippet will take you toward a compile-time error, because there is no initialization, since it's evaluated at run time.
Points to Remember
Compile-time constant
Can't be declared static
Can't be modified or changed
Can be of any type of Access Modifier
Local scope
Needs to get initialized
Declared at the time of declaration
Static
The static keyword is used to declare a static member. If we are
declare a class as a static class then in this case all the class
members must be static too. The static keyword can be used effectively
with classes, fields, operators, events, methods and so on
effectively.
Consider ff. code:
class ReadOnly
{
static int i = 11;
public static void disp()
{
Console.WriteLine(i);
}
}
Explanation:
This code will show no error and produce a result (11), since we declared its value to be static at the time of declaration. So we can access it depending on our use in the program.
But how about this:
class ReadOnly
{
int i = 9;
public static void disp()
{
Console.WriteLine(i);
}
}
This snippet above will show an error, because we didn't declare a value for the static and we are trying to access it within a method. We can't do that.
Points to Remember:
Can't be used with indexers
Works with constructors too
By default it is private
Can be parameterized or public too
If its applied to a class then all the class members need to be static
You can read more about above explanation here: constant vs readonly vs static
Additional note for static methods.
Consider ff. code:
public class SomeClass {
public string SomeMethod() {
return "Hello, World.";
}
}
When you want to Access SomeMethod of SomeClass, you need to instantiate SomeClass first:
var some = new SomeClass();
string result = some.SomeClass(); //this will set result as "Hello, World."
Compared to a static method:
public class SomeClass {
public static string SomeMethod() {
return "Hello, World.";
}
}
When accessing SomeMethod, you don't need to instantiate SomeClass. You can access it directly by:
string result = SomeClass.SomeMethod(); //this will give "Hello, World."
Which is the best way to declare a constant?
Its not the best, its the only way: const double G = 9.8;.
Or (...) static double G { get; set; }
Thats not a constant! Constant means constant: 1 is a constant, 'c'is a constant, PI is a constant... they represent values that don't change, ever!. Your second implementation of G can change, therefore its not a constant.
Also, its important you notice that constants are known at compile time, there is no evaluation needed at runtime.
This is the reason why any reference type const (expect string which has specific compiler support through string literals) can only be initialized to null, any other option would need to be evaluated at runtime.
Its also the reason why only a finite set of value types can be declared as const too. All of them are existing types in the framework and.. surprise, surprise, they all have compiler literal constant support: 1, 'c', 9.8 or 0.25M but not 01/01/2017 (how else would the compiler know the values before runtime?).
Another interesting question you didn't make is: what about static readonly?
You can think of static readonly as "the poor man's" const. Its often used to circumvent the limitations const offers concerning what types and initializing values are allowed.
It is almost the same as a constant, but there are a few important and decisive differences:
It can change; although it is readonly, you can change it's value inside the static constructor of the declaring type. const can never change after initialized.
It is evaluated at runtime, not compile time as a true const.
Any type can be declared as a static readonly and initialized to any valid value as you would do with any regular field.
As a nittpicking side note, you shouldn't make G a constant ;). It changes, and quite a bit. G in Ecuador is different from G in the North Pole.
const variables are assigned values at time of definition.
They are available at compile time. You can even use a compile time evaluate-able expression at compile time. But once a value has been assigned to a const variable, it cannot be changed at any other time.
Using static field means the value will remain same for every user of the application, but this value can be changed by code in any of the classes, and it will change for every user of the application.
Do not use static for constants, use const only. const are by default static, and you cannot use static keyword with it.
Check this
void Main()
{
// You will not be able to change value for const variable.
Console.WriteLine(Myclass.G);
// You will be able to change value for static variable,
// and this change will impact all users of the application.
// For every user, this field will store value of 10 now.
// That will not be required or desired code behavior.
Myclass1.G = 10;
Console.WriteLine(Myclass1.G);
}
// Normal class with const field
class Myclass
{
public const double G=9.8;
}
//static class with static constructor
static class Myclass1
{
public static double G{get;set;}
static Myclass1()
{
G=9.8;
}
}
Read More
Here you are talking about two different things, and this is their definition from MSDN:
1- static modifier: To declare a static member, which belongs to the type itself rather than to a specific object. The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, finalizers, or types other than classes.
2- const keyword: To declare a constant field or a constant local. Constant fields and locals aren't variables and may not be modified. Constants can be numbers, Boolean values, strings, or a null reference. Don’t create a constant to represent information that you expect to change at any time.
So a static member is defined for a Class (for all its instances, and that's why you can access it directly from the name of the Class) but can be modified. a const field of class can not be modified.
Ok, so this is really wierd. I have a private member, and I want to use it into Form2. I've made a public static method, so that I can get that member into Form2.
Here is my code:
private static AppController appController;
private BreadRepository breadRep;
private CakeRepository cakeRep;
private SandwichRepository sandwichRep;
public Form1()
{
InitializeComponent();
breadRep = new BreadRepository();
cakeRep = new CakeRepository();
sandwichRep = new SandwichRepository();
appController = new AppController(breadRep , sandwichRep, cakeRep);
}
public static AppController getController()
{
return appController;
}
I've tried to make the appController from Form1 public, but I get even more errors. Right now I get this:
Inconsistent accessibility: return type 'exemplu_map.controller.AppController' is less accessible than method 'exemplu_map.Form1.getController()'
Any ideas ?
Update:
Here is my AppController class:
class AppController
{
private BreadRepository breadRep;
private SandwichRepository sandwichRep;
private CakeRepository cakeRep;
public AppController(BreadRepository breadRep, SandwichRepository sandwichRep, CakeRepository cakeRep)
{
this.breadRep = breadRep;
this.sandwichRep = sandwichRep;
this.cakeRep = cakeRep;
}
public void writeToFile(String file)
{
StreamWriter wr = new StreamWriter(file);
String writeMe = "";
foreach(Bread e in breadRep.getAll())
{
writeMe = writeMe + e.getAll() + "\n";
}
foreach (Sandwich e in sandwichRep.getAll())
{
writeMe = writeMe + e.getAll() + "\n";
}
foreach (Cake e in cakeRep.getAll())
{
writeMe = writeMe + e.getAll() + "\n";
}
wr.Write(writeMe);
wr.Close();
}
}
I've changed AppController to public, but I get again, more errors. The same error, but for breadRep, cakeRep, sandwichRep.
The problem is, as #Selman22 explained, that your method is public, while its return value is internal. (Classes are internal by default.)
If both are public or internal, everything should work.
Making class public appeared to be difficult due to dependencies on other classes. Moreover, it could be not the best, since by default it is better to keep things less accessible.
Making the method internal solves the same problem from another end.
Anyway, #Selman22 was first :). I just added my two cents, so you should perhaps accept his answer :).
Accessibility is determined by the access level given to a type or member. It's important to note that the default access level is different for types/type members
The default access level for types is internal
The default access level for members is private
It is also important to note that private is not applicable to types (how can you construct a type if it is private - it could only ever construct itself), unless the type is nested in another type
Knowing this, it's easy to see why you would get errors in making your types public. In making a type public you are opening up your assembly to be referenced by other assemblies, meaning they can see the types within.
If your types are declared public and they have a public constructor, then it is expected that their public constructor can be called by an external assembly. It is because of this that all types which make up the constructor or any other public members of a type in your assembly must have public accessibility.
public class SomeClass
{
// This class and this constructor are externally visible
// The parameter of type SomeOtherClass must also be public in order
// for external assemblies to be able to construct this type
public SomeClass(SomeOtherClass someOtherClass) { }
}
// This would cause the issue you are having since this type is private but
// is included within a public contract (above), therefore the accessibility is 'inconsistent'
private class SomeOtherClass { }
I digress though - your issue, is with member accessibility
Your static member AppController is marked private meaning it can only be seen by the Form1 class (I'm assuming that's the class it resides in)
The solution (as shown by Alex D) could be to make the member internal instead of private. This means that the member can be seen by any types in the same assembly. private is only visible to the type that declares the member
If you make it too accessible (public) you will get the errors as shown above. internal keeps the inner workings within your assembly, meaning you don't get these accessibility issues.
This question already has answers here:
Struct constructor: "fields must be fully assigned before control is returned to the caller."
(5 answers)
Auto-properties and structs
(3 answers)
Closed 9 years ago.
The following code suggests I cannot use implicit properties with a struct:
public struct LimitfailureRecord
{
public LimitfailureRecord(string sampleCode)
{
SampleCode = sampleCode;
}
public string SampleCode {get; set;}
{
}
}
It fails to compile, with the error message
"Backing field for automatically implemented property
'blahblah.LimitfailureRecord.SampleCode'
must be fully assigned before control is returned to the caller.
Consider calling the default constructor from a constructor
initializer."
If I change the struct to a class it's fine.
What do I need to do to make this work as a struct? I'd rather not go to the lengths of backing fields (this is a heavily stripped down version of the real code) if I can avoid it.
With structs you have to call the default constructor in all other constructors:
public LimitfailureRecord(string sampleCode) : this()
{
SampleCode = sampleCode;
}
Use a constructor chaining like so:
public LimitfailureRecord(string sampleCode)
: this()
{
...
}
The reason is the auto-implemented property introduces a (generated) instance field for backing, as described. All instance fields must be assigned to in an instance constructor of a struct.
Actually the error text you quote describes the fix pretty well.
Something else: If you keep the set accessor of your property public you will have a mutable struct. Most people agree that mutable structs should be avoided and are "evil" because their copy-by-value semantics and the possibility of mutating an existing struct value (as in record.SampleCode = "Here's a new string for an old object";) don't go well together. Check the threads on mutable and immutable structs.
You either need to call the default constructor or change the method name.
So;
public struct LimitfailureRecord
{
public void init(string sampleCode)
{
SampleCode = sampleCode;
}
public string SampleCode { get; set; }
}
Will work or just make the method definition; LimitfailureRecord(string sampleCode) : this()
The later is better because it only requires one call to make things work. If you go the init route you have do do new LimiFfailureRecord then call init after. structs in C# simply require you to call the default constructor, this isn't the case with classes which is why it will compile if you change it to a class.
Ok so lets say I have a structure A like that:
Struct A{
private String _SomeText;
private int _SomeValue;
public A(String someText, int SomeValue) { /*.. set the initial values..*/ }
public String SomeText{ get { return _SomeText; } }
public int SomeValue{ get { return _SomeValue; } }
}
Now what I want to be able to do is to return that Structure A as a result of a method in a Class ABC, like that:
Class ABC{
public A getStructA(){
//creation of Struct A
return a;
}
}
I don't want any programmer using my library (which will have Struct A and Class ABC and some more stuff) to ever be able to create an instance of Struct A.
I want the only way for it to be created is as a return from the getStructA() method. Then the values can be accessed through the appropriate getters.
So is there any way to set a restrictions like that? So a Structure can't be instantiated outside of a certain class? Using C#, .Net4.0.
Thanks for your help.
---EDIT:----
To add some details on why am I trying to achieve this:
My class ABC has some "status" a person can query. This status has 2 string values and then a long list of integers.
There never will be a need to create an object/instance of "Status" by the programmer, the status can only be returned by "getStatus()" function of the class.
I do not want to split these 3 fields to different methods, as to obtain them I am calling Windows API (p/invoke) which returns similar struct with all 3 fields.
If I was indeed going to split it to 3 methods and not use the struct, I would have to either cache results or call the method from Windows API every time one of these 3 methods is called...
So I can either make a public struct and programmers can instantiate it if they want, which will be useless for them as there will be no methods which can accept it as a parameter. Or I can construct the library in such a way that this struct (or change it to a class if it makes things easier) can be obtained only as a return from the method.
If the "restricted" type is a struct, then no, there is no way to do that. The struct must be at least as public as the factory method, and if the struct is public then it can be constructed with its default constructor. However, you can do this:
public struct A
{
private string s;
private int i;
internal bool valid;
internal A(string s, int i)
{
this.s = s;
this.i = i;
this.valid = true;
}
...
and now you can have your library code check the "valid" flag. Instances of A can only be made either (1) by a method internal to your library that can call the internal constructor, or (2) by the default constructor. You can tell them apart with the valid flag.
A number of people have suggested using an interface, but that's a bit pointless; the whole point of using a struct is to get value type semantics and then you go boxing it into an interface. You might as well make it a class in the first place. If it is going to be a class then it is certainly possible to make a factory method; just make all the ctors of the class internal.
And of course I hope it goes without saying that none of this gear should be used to implement code that is resistant to attack by a fully-trusted user. Remember, this system is in place to protect good users from bad code, not good code from bad users. There is nothing whatsoever that stops fully trusted user code from calling whatever private methods they want in your library via reflection, or for that matter, altering the bits inside a struct with unsafe code.
Create a public interface and make the class private to the class invoking it.
public ISpecialReturnType
{
String SomeText{ get; }
int SomeValue{ get; }
}
class ABC{
public ISpecialReturnType getStructA(){
A a = //Get a value for a;
return a;
}
private struct A : ISpecialReturnType
{
private String _SomeText;
private int _SomeValue;
public A(String someText, int SomeValue) { /*.. set the initial values..*/ }
public String SomeText{ get { return _SomeText; } }
public int SomeValue{ get { return _SomeValue; } }
}
}
What exactly are you concerned about? A structure is fundamentally a collection of fields stuck together with duct tape. Since struct assignment copies all of the fields from one struct instance to another, outside the control of the struct type in question, structs have a very limited ability to enforce any sort of invariants, especially in multi-threaded code (unless a struct is exactly 1, 2, or 4 bytes, code that wants to create an instance which contains a mix of data copied from two different instances may do so pretty easily, and there's no way the struct can prevent it).
If you want to ensure that your methods will not accept any instances of a type other than those which your type has produced internally, you should use a class that either has only internal or private constructors. If you do that, you can be certain that you're getting the instances that you yourself produced.
EDIT
Based upon the revisions, I don't think the requested type of restriction is necessary or particularly helpful. It sounds like what's fundamentally desired to stick a bunch of values together and store them into a stuck-together group of variables held by the caller. If you declare a struct as simply:
public struct QueryResult {
public ExecutionDuration as Timespan;
public CompletionTime as DateTime;
public ReturnedMessage as String;
}
then a declaration:
QueryResult foo;
will effectively create three variables, named foo.ExecutionDuration, foo.CompletionTime, and foo.ReturnedMessage. The statement:
foo = queryPerformer.performQuery(...);
will set the values of those three variables according to the results of the function--essentially equivalent to:
{
var temp = queryPerformer.performQuery(...);
foo.ExecutionDuration = temp.ExecutionDuration
foo.CompletionTime = temp.CompletionTime;
foo.ReturnedMessage = temp.ReturnedMessage;
}
Nothing will prevent user code from doing whatever it wants with those three variables, but so what? If user code decides for whatever reason to say foo.ReturnedMessage = "George"; then foo.ReturnedMessage will equal George. The situation is really no different from if code had said:
int functionResult = doSomething();
and then later said functionResult = 43;. The behavior of functionResult, like any other variable, is to hold the last thing written to it. If the last thing written to it is the result of the last call to doSomething(), that's what it will hold. If the last thing written was something else, it will hold something else.
Note that a struct field, unlike a class field or a struct property, can only be changed either by writing to it, or by using a struct assignment statement to write all of the fields in one struct instance with the values in corresponding fields of another. From the consumer's perspective, a read-only struct property carries no such guarantee. A struct may happen to implement a property to behave that way, but without inspecting the code of the property there's no way to know whether the value it returns might be affected by some mutable object.
I've got a class A with a public field b
class A
{
public static string b;
}
but now I want to make b dynamic so I call it anything. So I can make the class a DynamicObject
class A : DynamicObject
{
}
but I the compiler doesn't let me now call A.dynamicThing cos I have to instantiate A as dynamic.
How can I mangle c# further to make this work?
I don't belive you're going to find a way to make this work. It's not just the DynamicObject that makes things work. The declaration as a variable of the "dynamic" data type is what tells the compiler to actually use the DynamicObject base to resolve the member access. With static access direct to the class, you don't have that. So I really just don't think this is going to work in C# unless that changes in the future.
It's not possible right now with .NET 4
more information in this article.
I think I understand now - the closest you can get is by using an ExpandoObject :
dynamic foo = new ExpandoObject();
foo.somethinghere = "bar";
foo.dynamicThing = "baz";
Edit:
I don't think its possible to re-route the access to a static property of a class
to an expando object if the name of the property does not match - how would the compiler know that that's what you meant to do? You are getting a compile time error after all, not a runtime error.
From MSDN:
When a field, method, property, event,
operator, or constructor declaration
includes a static modifier, it
declares a static member. In addition,
a constant or type declaration
implicitly declares a static member.
Static members have the following
characteristics:
When a static member M is referenced in a member-access (Section 7.5.4)
of the form E.M, E must denote a type containing M.
...
public class FakeDynamicMethodInvoker : DynamicObject
{
// your code here
}
public class FakeDynamicWrapper<T>
{
static FakeDynamicWrapper()
{
DynamicStaticField = (dynamic)new FakeDynamicMethodInvoker();
}
public static T DynamicStaticField{ get; set; }
}
public class RealClassWithDynamicStaticField: FakeDynamicWrapper<dynamic>
{
}
somewhere in a code:
RealClassWithDynamicStaticField.DynamicStaticField.AnyMethod();
C# doesn't let you really rename variables to some dynamic name at runtime. Your question is mangled.
If you are wanting variable b to have a dynamic object at runtime, then use the dynamic keyword.
Example:
dynamic b = GetBValue();
b.SomeOperation(); // the type of "b" will be evaluated/chosen at runtime.
Old question but worth to answer :)
Static constructors are the answer to these problems.
https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
public class MyClass
{
public static dynamic StaticDynamicObject;
static MyClass()
{
StaticDynamicObject = new ExpandoObject();
StaticDynamicObject.Prop = "woohoo!";
}
}