I tried to create a class library that is being used in a winforms application in C#.
In my application I have input from a textbox and through a button click I'm instantiating
my event with one parameter (from the textbox). I tried to create a constructor with
this one parameter - but to no avail. It seems if I just add a class to be existing
project I can do this but not when referencing a class library.
Just wanted to find a way to use a one parameter constructor within a class library
if possible. Please help. (this may not work logically because when I reference the
class library - I am actually going outside the original assembly - but maybe....)
If your new class library is in a separate C# project you need to set a reference to that project from your WinForms app before you can use the class.
Of course I'm trying to read between the lines of your original post. It sounds like you know how to make it work, just not when the class is defined in a seperate project. If I've misunderstood, please give more info.
Not enough site experience to upvote or comment myself yet, but DRapp's answer fixed my problem. Since the original question is a bit vague I thought I'd detail what I was seeing a bit more:
I am writing a metro application in C++ which references a class library created in C#. Creating objects exported from the C# module was working fine, unless their constructors had parameters.
// C# file exported to .winmd class library for use in metro app
namespace A
{
public sealed class B
{
public B(bool bTest)
{}
// Other methods/members...
}
}
// C++ metro app referencing .winmd created from C# above
...
A::B^ spB = ref new A::B(bTest); // Throws an exception
Attempting to create an object of type B from the C# module in C++ would throw an exception, with a somewhat cryptic "WinRT transform error" show in the output log.
To fix this, I was able to do what DRapp suggested and add a default constructor to B:
// C# file exported to .winmd class library for use in metro app
namespace A
{
public sealed class B
{
public B()
{}
public B(bool bTest)
{}
// Other methods/members...
}
}
No more exception. :)
it sounds like you don't have two constructors... (overloaded) for your class such as
public class YourClass
{
public YourClass()
{
}
public YourClass(String OneParameter) // this OVERLOADS the default No parameter one
{
DoWhatever with your OneParameter...
}
}
Related
I have a Controls.dll file that has a class named Textbox. I want to inherited from this something like this:
class TextArea : Textbox {
}
How can I do this in C#, Microsoft Visual Studio?
Essentially, the same way as you would with any other class your project knows about.
Add a reference to the DLL in your project (so your project knows about the classes inside the DLL)
[optionally] Add a using that references the namespace the Textbox from the DLL to the top of the new class you write
Write the rest of the class that extends the Textbox:
using SomeDllNamespace.Controls.Text;
namespace MyControls {
public class TextArea : Textbox {
}
}
Or without using:
namespace MyControls {
public class TextArea : SomeDllNamespace.Controls.Text.Textbox {
}
}
C# I have a DLL file and I need to make a class that inherits from a class that's in the
DLL file?
Yes, and you should know it because....
....all the classes you inherit from in C# code are actually stored in dlls. So, if you inherit from anything or use anything it is stored in another dll than your program - that includes simple types as integer etc. which are defined in dll's.
You do that by learning the language. Then add the dll's (as nuget packages preferred) in dependencies, add the using statement or qualify the class name properly, as you learned when learning the language.
I want to use c# code app in tcl using COM > twapi > tcl path.
By studying "call c# code from tcl" wiki page I understood two things.
We need to compile c# code with com interface register VS option. Then use that namespacename.classname to create object instance. But it is not clear how twapi (or tcom) will use that com (or link). Can you please explain in more details. Thanking you in advance.
C# code
using System;
namespace MyClassLib
{
public class Class1
{
public Class1() {}
public int Double (int val) { return val * 2 ; }
}
}
When the project is registered for COM Interop and built, the class is registered in the system's Registry as a provider for that class name. The tcom package knows how to use that information. When you do:
set myCom [tcom::ref createobject "ClassLibrary1.Class1"]
It goes away and asks the COM service that's built into Windows to make an instance of that object and give a reference to it back to you. That reference is what is stored in the variable. You can then invoke methods of the object; the syntax for that is Tcl-ish rather than C#-ish, but the models line up.
$myCom Double 6
Yes, there's a lot of complexity going on behind the scenes, mostly centred on IDispatch and its related interfaces.
As among many, I have a .NET solution with many projects underneath.
The problem is this:
I use some lines of code repetitively in my project. Its kind of copy-pasting and I really hate that..
My idea is to move all these code in to a separate helper class but the following questions are preventing this idea:
The security aspect --> When I move this code out of my project, this means that somebody can still access it. If it were in my project, I could provide it security by making the concerned function "private".
So, the question is how to avoid code repetition but at the same time doing it securely ?
Some code to explain my concern:
project A (of Solution S)
private Foo SomeSecureCode(IMyInterface interfaceObject)
{
//Same some lines of code
}
project B (of Solution S)
private Foo SomeSecureCode(IMyInterface interfaceObject)
{
//Same some lines of code as above
}
Instead, moving this Function in a helper class but how making it securely?
(Minor details: I am using .NET version 4 with VS 2010)
This could be a solution:
Moven the class from project A to an other project (B) and make the class internal
Sign the projects that want't t use the class with sn.exe and sign the project in the properties of the project.
In project B add this to AssemblyInfo under the Properties folder of project B.
[assembly: InternalsVisibleTo("Full.Assembly.Name.Here, PublicKey="Cut and past the public key of project A here>")]
Now you can use it only in project A and B.
To sign the project:
Run sn.exe
Call the result of Sn.exe sn.key
Add sn.key to your project
Open the properties of the project you wnt to sign (Alt+Enter)
Go to tab "Signing
Check the checkbox "Sign the assembly
Choose the strong name key in the combobox
Compile the project
Now the project is signed you can make internals visible in an other project by adding the InternalsVisibleTo attribute to the AssemblyInfo of the project with the internal class.
maybe this points in right direction:
InternalsVisibleToAttribute: Specifies that types that are ordinarily visible only within the current assembly are visible to a specified assembly.
Could you use inheritance and have the "helper" class be the base of the classes that need it?
sealed class A : C { }
sealed class B : C { }
abstract class C {
protected Foo SomeSecureCode(IMyInterface interfaceObject);
}
You can also use object composition and internal classes.
In one assembly:
class A {
private Helper _helper;
private Foo SomeSecureCode(IMyInterface interfaceObject) {
return _helper.SomeSecureCode(interfaceObject);
}
}
And in a different assembly:
internal class Helper {
public Foo SomeSecureCode(IMyInterface interfaceObject) {
// your code here
}
}
Then use the Assembly InternalsVisibleTo attribute in the assembly containing Helper to allow assemblies that need to see Helper to access it.
Also, keep in mind that anyone using your assembly could access and call your private method(s) using the Reflection API, and tools like dotpeek will let them see your code with only a little bit of information lost.
I want to build a Windows Store class library using source code from a regular .NET Framework class library. Ideally, I do not want to modify the original source code files.
In some of the source code files from the .NET Framework library, static members are used from a class that is defined in both the regular .NET Framework API and the .NET for Windows Store apps API, but where only a subset of the .NET Framework members are available for Windows Store.
One specific example is System.IO.Path, where the GetFullPath method is not available for Windows Store apps.
It is fairly straightforward to incorporate a replacement for this method in my Windows Store class library and have the original source code invoke this method instead. My question is, is there any way I can do this without modifying the original source code file?
So far, I have not been able to figure out a satisfactory solution to this problem, but I have solved it for my Windows Store class library by implementing e.g. the Path.GetFullPath(string) method in another namespace:
namespace WindowsStoreLib.System.IO {
public static class Path {
public static string GetFullPath(string path) { ... }
}
}
and then adding a preprocessor directive in the original files:
#if NETFX_CORE
using Path = WindowsStoreLib.System.IO.Path;
#endif
Is there an alternative solution to this issue that does not require modification of the original source code files?
No, you cannot, simply.
When I'm doing cross-platform stuff I tend to write a utility class that has different implementations (via #if) for different platforms - then my core code just calls the utility class.
I've been doing something like this lately with Entity Framework classes since I needed to add a specific output of 2 fields as 1 and it wiped it out from the designer.cs on every update. However they were not static classes or static methods, but should work with same.
Create a new class file with the name of the class you want to extend and use the partial qualifier.
namespace WindowsStoreLib.System.IO {
public partial static class Path {
public static string GetFullPath(string path) { ... }
}
}
As Marc said, the preprocessor directive seems to be the only solution.
But when I read "static class" and "existing class", the first thing coming to my mind is "extension method". What would happen if you created an extension method for Path in the same namespace where your code is?
namespace MyNamespace.WhereMyCodeIs
{
using System.IO;
public static class ExtensionMethods
{
public static string GetFullPath(this Path pathObject, string path)
{
// Implementation
}
}
}
I am really not sure if this would work out but maybe there is a work around we could find around this.
An existing Visual C++ application makes the following call;
BOOL bRet = pMyClass.CreateDispatch("BlahBlah.MyClass");
if ( !bRet )
{
// Error handling snipped
}
else
{
pMyClass.MyMethod();
pMyClass.ReleaseDispatch();
}
pMyClass is a class which was apparently auto-generated by ClassWizard, and it inherits from COleDispatchDriver.
The actual DLL to which it refers is a VB6 one, and this is being migrated to C# as part of an effort to move away from VB in general.
My question is... is there anything special I need to do to make sure that the C# assembly will work in the same way as the original VB6 module did? Currently, the C# looks like this;
[ComVisible(true)]
[ProgId("BlahBlah.MyClass")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class MyClass
{
...
public void MyMethod()
{
...
}
}
Is this sufficient? Are there any gotchas to be aware of when setting public string fields (not shown in code) on MyClass?
Note that I'm not the original author of this code - it's from a legacy system and I'm just doing the migration.
The CreateDispatch call uses late binding to talk to the COM server. ClassInterfaceType.AutoDispatch. Using AutoDual is fine, that also includes late binding support. With the significant advantage that you can make it a lot faster some day. Late binding isn't cheap.