I am new to c# and just switched from c++ to c#.
I was doing something like this in c++:
Class A
{
public : A(char *argv);//declaration of constructor
}
then in main i was doing like this:
int main(int argc, char **argv)
{
A Obj(argv[1]);
}
then definition of constructor i do like this :
A::A(char * argv)
{
//Here i use this command line argument argv which contains a file.
}
I tried to write equivalent code in c# which is as follows:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace shekhar_final
{
class Huffman
{
public int data_size,length,i,is_there, total_nodes;
string code;
Huffman(char *args);
}
public Huffman(char *args) //called from MyClass Line:16
{
using (var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) //Line : 18
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte processingValue = stream.ReadByte();
}
}
}
public class MyClass
{
public static void Main(string[] args)
{
Huffman ObjSym =new Huffman(args);//object creation
}
}
}// Line:34
The couple of errors i got are ://I have indicated the line corresponding to the errors in my code
shekhar_c#.cs(16,25): error CS1525: Unexpected symbol `Huffman', expecting `class', `delegate', `enum', `interface', `partial', or `struct'
shekhar_c#.cs(18,33): error CS1530: Keyword `new' is not allowed on namespace elements
shekhar_c#.cs(18,36): error CS1525: Unexpected symbol `BinaryReader', expecting `class', `delegate', `enum', `interface', `partial', or `struct'
shekhar_c#.cs(18,79): warning CS0658: `value' is invalid attribute target. All attributes in this attribute section will be ignored
shekhar_c#.cs(34,1): error CS8025: Parsing error
Compilation failed: 4 error(s), 1 warnings
Could you please help me in writing c# equivalent of this c++ (removing these errors). Extra guidance are also welcome because i am beginner to c#.
Unlike C++ where you have a choice of combining the declaration and the definition of a member function in the header, or placing the declaration in the header and the implementation in the cpp file, in C# there is no such choice: if a function has a body (i.e. it is not abstract), the body needs to be part of the declaration:
class Huffman
{
public int data_size,length,i,is_there, total_nodes;
string code;
Huffman(string args) {
using (var stream = new BinaryReader(System.IO.File.OpenRead(args)))
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte processingValue = stream.ReadByte();
}
}
}
}
In C#, declarations and implementations go together:
namespace shekhar_final
{
class Huffman
{
public int DataSize {get; set;}
public int Length {get; set;}
public int I {get;set;}
public int IsThere {get;set;}
public int TotalNodes {get;set;}
private string code;
public Huffman(string[] args) //called from MyClass Line:16
{
using (var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) //Line : 18
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte processingValue = stream.ReadByte();
}
}
}
}
public class MyClass
{
public static void Main(string[] args)
{
Huffman objSym = new Huffman(args);//object creation
}
}
}// Line:34
You don't define methods ahead of time in C# - they're defined within the class itself. Try this instead:
class Huffman
{
public int data_size,length,i,is_there, total_nodes;
string code;
public Huffman(char *args) //called from MyClass Line:16
{
using (var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) //Line : 18
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte processingValue = stream.ReadByte();
}
}
}
}
public class MyClass
{
public static void Main(string[] args)
{
Huffman ObjSym =new Huffman(args); //Here is the error
}
}
The main phlosophy between C# and C++ are different. In C++ you have a header file and an implementation file. In C#, everthing needs to be within a class. So, you declare the constructor to the class and put the implementation within it.
class funny {
public funny() {
... add your constructor stuff here
}
... other stuff ...
}
C# requires constructors to be defined within the class:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace shekhar_final
{
public class Huffman{
public int data_size,length,i,is_there, total_nodes;
string code;
public Huffman(string[] args) //called from MyClass Line:16
{
using (var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) //Line : 18
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte processingValue = stream.ReadByte();
}
}
}
}
public class MyClass
{
public static void Main(string[] args)
{
Huffman ObjSym =new Huffman(args);//object creation
}
}
}// Line:34
In c# you do not separate declaration and definition. There is no such concept as declaration in c# since all the types exist together in an assembly. If you wish to use multiple files in c3 for classes you can use the concept of partial classes.
Related
using System;
namespace AssemblyOne
{
public class AssemblyOneClassOne
{
protected internal int ID = 101;
public int id = 102;
public void Print()
{
Console.WriteLine("Abdullah is a handsome hunk!");
}
}
public class AssemblyOneClassTwo
{
public void SampleMethod()
{
AssemblyOneClassOne a1 = new AssemblyOneClassOne();
Console.WriteLine(a1.ID);
}
}
public class A
{
public static void Main()
{
AssemblyOneClassTwo a2 = new AssemblyOneClassTwo();
a2.SampleMethod();
Console.ReadKey();
}
}
}
using System;
using AssemblyOne;
namespace AssemblyTwo
{
public class AssemblyTwoClassOne
{
AssemblyOneClassOne instance = new AssemblyOneClassOne();
instance.Print();//Over here I am getting compile time error, 'instance' does not exist in the current context, 'instance.Print' does not exist in the current context
}
}
As far as I know, public types can be accessed in anywhere in the same assembly as well as in another assembly
Yes, public types can be accessed from another assembly but your method Print() should be called inside a method of class AssemblyTwoClassOne.
Something like this -
namespace AssemblyTwo
{
public class AssemblyTwoClassOne
{
AssemblyOneClassOne instance = new();
public void Method() => instance.Print();
}
}
When trying to cast a class which defines a custom generic to the subclass I get an error. What did I wrong?
using System.Collections.Generic;
interface IStorageComponent { }
abstract class CollectionManager<T> where T : IStorageComponent { }
class Bar : IStorageComponent { }
class Foo : CollectionManager<Bar> { }
class Storage
{
static int Main(string[] args)
{
List<CollectionManager<IStorageComponent>> manager = new List<CollectionManager<IStorageComponent>>
{
new Foo() // <-- cannot convert from 'Foo' to 'CollectionManager<IStorageComponent>'
};
return 0;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm creating a DLL for a application that I make.
But I got a error when I added the DLL as refference to the console Application but do not know what it means this is the error:
An unhandled exception of type 'System.TypeInitializationException' occurred in ConsoleApplication1.exe
And this is my dll class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace Steap
{
public class SteapAPI
{
public static String URL
{
get;
set;
}
public static XmlReader r = XmlReader.Create(URL + "?xml=1&l=english");
public int getSteamID64()
{
int ID = 0;
r.ReadToFollowing("steamID64");
ID = r.ReadContentAsInt();
return ID;
}
public string getSteamID()
{
string ID = String.Empty;
r.ReadToFollowing("steamID");
ID = r.ReadContentAsString();
return ID;
}
public int getVac()
{
int Vac = 0;
r.ReadToFollowing("vacBanned");
Vac = r.ReadContentAsInt();
return Vac;
}
public bool hasVac()
{
if (getVac() == 0)
{
return false;
}
else
{
return true;
}
}
// =================== [ Aliases
public string getName()
{
return getSteamID();
}
}
}
Console application code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Steap;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
SteapAPI sapi = new SteapAPI(); // TypeInitializationException was unhandled error here
SteapAPI.URL = "http://steamcommunity.com/id/bluesephire";
Console.ReadKey();
}
}
}
What is wrong or what is missing
You have exception during initialization of static field of your class that leads to failure to load the class and hence the TypeInitializationException exception.
Particular line:
public static XmlReader r = XmlReader.Create(URL + "?xml=1&l=english");
URL is not initialized at the time method called (and even if it would have static value like URL=#"c:\file.txt" there is no guarantee that one field will be initialized first.
Note from that point any access to the SteapAPI class will throw the TypeInitializationException even if it is not touching fields directly involved into original exception.
In this case you shouldn't be using static fields. Static fields will cause huge problems if you ever create two SteapAPI objects, in that when you set one URL, it will overwrite the other one, and you'll never be able to re-initialize the XmlReader.
Here is how the API class should be rewritten to be a full instance class:
namespace Steap
{
public class SteapAPI
{
public String URL
{
get;
set;
}
public XmlReader r;
public SteapAPI(string url)
{
URL = url;
//NOTE: This is wrong! You can't create an XmlReader with a URL
//and expect it to fetch a web resource.
r = XmlReader.Create(URL + "?xml=1&l=english");
}
public int getSteamID64()
{
int ID = 0;
r.ReadToFollowing("steamID64");
ID = r.ReadContentAsInt();
return ID;
}
public string getSteamID()
{
string ID = String.Empty;
r.ReadToFollowing("steamID");
ID = r.ReadContentAsString();
return ID;
}
public int getVac()
{
int Vac = 0;
r.ReadToFollowing("vacBanned");
Vac = r.ReadContentAsInt();
return Vac;
}
public bool hasVac()
{
if (getVac() == 0)
{
return false;
}
else
{
return true;
}
}
// =================== [ Aliases
public string getName()
{
return getSteamID();
}
}
And then to use it in your program:
class Program
{
static void Main(string[] args)
{
SteapAPI sapi = new SteapAPI("http://steamcommunity.com/id/bluesephire");
Console.ReadKey();
}
}
Its a minor change but the benefits are huge, you should learn more about using constructors and the drawbacks of static fields/properties as it applies to multiple instances. Just remember, a static field/property of a non-static class is shared between all "instances" of the class, so setting one will set all "instances" of that class to the new value. This is especially important when doing I/O operations and file/resource reading/writing.
Attempting to make a protected internal member of a protected internal class within a public class results with the following issue:
Inconsistent accessibility: field type
'what.Class1.ProtectedInternalClass' is less accessible than field
'what.Class1.SomeDataProvider.data'
The accessibility should be equivalent, as far as I know.
Where am I mistaken?
Origination class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace what
{
public class Class1
{
// This class cannot be modified, is only
// here to produce a complete example.
public class PublicClass
{
public PublicClass() { }
}
protected internal class ProtectedInternalClass : PublicClass
{
public ProtectedInternalClass() { }
public void SomeExtraFunction() { }
}
public class SomeDataProvider
{
public int AnInterestingValue;
public int AnotherInterestingValue;
protected internal ProtectedInternalClass data; //<--- Occurs here.
public PublicClass Data { get { return data; } }
}
public static SomeDataProvider RetrieveProvider()
{
SomeDataProvider provider = new SomeDataProvider();
provider.data = new ProtectedInternalClass();
provider.data.SomeExtraFunction();
return provider;
}
}
}
Verifying protected and internal properties, same assembly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace what
{
public class Class2 : Class1
{
public Class2()
{
var pi = new ProtectedInternalClass();
var provider = new SomeDataProvider();
provider.data = pi;
}
// no errors here
}
public class Class3
{
public Class3()
{
var pi = new Class1.ProtectedInternalClass();
var provider = new Class1.SomeDataProvider();
provider.data = pi;
}
// no errors here
}
}
Verifying protected and internal properties, different assembly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace some_other_assembly
{
public class Class4 : what.Class1
{
public Class4()
{
var pi = new ProtectedInternalClass();
var provider = new SomeDataProvider();
provider.data = pi;
}
// no errors here
}
public class Class5
{
public Class5()
{
var pi = new what.Class1.ProtectedInternalClass(); // <--- Inaccessible due to protection level, as it should be.
var provider = new what.Class1.SomeDataProvider();
provider.data = pi; // <--- Intellisense implies inaccessible, but not indicated via error.
}
}
}
The protected applies to different classes, and this can be seen with
class Derived : what.Class1.SomeDataProvider // note: Derived is not a nested class
{
public void f()
{
var data = this.data;
}
}
in a different assembly.
this.data has to be accessible, since the class derives from SomeDataProvider. Its type, ProtectedInternalClass, is not accessible, since the class does not derive from Class1.
I am trying to make an instance of a class based on a string that will be retrieved from the User Interface, and then I want to access the properties of the instance of the class.
Here is an overview of what I have so far -
namespace MamdaAdapter
{
public interface IExchange
{
string GetTransport();
}
}
namespace MamdaAdapter
{
public class Exchange
{
public class Arca : IExchange
{
private const string _Transport = "tportname";
public string GetTransport()
{
return _Transport;
}
}
public static IExchange DeriveExchange(string ExchangeName)
{
IExchange SelectedExchange = (IExchange)Activator.CreateInstance(Type.GetType(ExchangeName));
return SelectedExchange;
}
}
}
namespace MyUserInterface
{
public class MainForm
{
private void simpleButton1_Click(object sender, EventArgs e)
{
IExchange SelectedExchange = Exchange.DeriveExchange("Exchange.Arca");
Console.WriteLine(SelectedExchange.GetTransport());
}
}
}
UPDATE:
Right now, I'm getting an Exception that says the "Value cannot be null" which to me means that it is unable to create the instance of the class given the string provided -
The problem here is how you specify the name of your class:
First, specify the namespace. Second, since Arca is an inner class you must use '+' instead of '.'
(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");
Assuming you UI doesnt expose the full type name, you typically want a dictionary to associate the display name to the type:
Dictionary<string, Type> _associations = new Dictionary<string, Type>();
Then, you simply instantiate the new object:
if(_associations.ContainsKey(someString))
{
Type selectedType = _associations[someString];
return Activator.CreateInstance(selectedType) as IExchange;
}
throw new ApplicationException("No type defined for that string yo");
If the string is not known at compile time, you basically need to check for the existance of the type:
var type = Type.GetType(someString);
if(type != null)
{
// Do Stuff
}
I wrote a small c# console application to simulate your need, tested ok, hope it helps:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MamdaAdapter;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
IExchange SelectedExchange = Exchange.DeriveExchange("MamdaAdapter.Arca");
Console.WriteLine(SelectedExchange.GetTransport());
}
}
}
namespace MamdaAdapter
{
public interface IExchange
{
string GetTransport();
}
}
namespace MamdaAdapter
{
public class Arca : IExchange
{
private const string _Transport = "tportname";
public string GetTransport()
{
return _Transport;
}
}
}
namespace MamdaAdapter
{
public class Exchange
{
public static IExchange DeriveExchange(string ExchangeName)
{
IExchange SelectedExchange = (IExchange)Assembly.GetAssembly(typeof(IExchange)).CreateInstance(ExchangeName, false, BindingFlags.CreateInstance, null, null, null, null);
return SelectedExchange;
}
}
}
If the Type you are looking for is not defined in the same assembly that is executing Type.GetType you must use the AssemblyQualifiedName (something like MyNamespace.MyClass, MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089), even the FullName is not enough. Otherwise you could first get the assembly containing the class and then execute the GetType method of the Assembly class.