.Net how to make a constructor for a partial class? - c#

I have a partial class with a constructor, but the constructor is throwing an error because 'a member with the same signature is already declared' (a constructor of the same name exists in the other partial class). How do I make a constructor for a partial class when the name is already being used?
public partial class DigitalArchivesAssetsDataContext
{
public DigitalArchivesAssetsDataContext()
: base(System.Configuration.ConfigurationManager.ConnectionStrings["digitalArchivesAssets"].ConnectionString, mappingSource)
{
OnCreated();
}
}

You can't. The compiler essentially merges the text of all the partial classes together in to one class when the project is built. You can't have more than one method (including constructors) with the same name and signature per class.
One option is to use a different signature for the constructor, or modify your architecture to not need a constructor. For instance, you could use the existing constructor and have some kind of Initialize method that runs the code from your other constructor.
You could also use "Partial Methods". These are methods marked as partial that you could call from the existing constructor "if they exist". They are designed as extension points for partial classes that come from a code generator, but you may be able to make use of them too. See MSDN for more information.

You can not create multiple constructors with matching signature in to the splitted partial classes because at the compile time both the parts are merged together to generate a single class file. for example
class ClassRoom
{
private int boycount; //field
public ClassRoom() //default constructor
{
boycount = 30;
}
public ClassRoom(int bcount) //overloaded constructor
{
boycount = bcount;
}
public double Avg() //method
{
//statements goes here
}
}
In above example we can split the class like this.
//Calculation1.cs
partial class ClassRoom
{
private int boycount; //field
public ClassRoom() //default constructor
{
boycount = 30;
}
}
//Calculation2.cs
partial class ClassRoom
{
public ClassRoom(int bcount) //overloaded constructor
{
boycount = bcount;
}
public double Avg() //method
{
//statements goes here
}
}
Hope it is clear.

Related

How to automaticly provide constructors from generic base class in C#?

So I have a generic base class like this:
class DatabaseDatasourceClassBase<DomainClass>
where DomainClass : new()
{
protected DomainClass m_DbObject;
public AddableDatabaseDatasourceClassBase()
{
m_DbObject = new DomainClass();
}
public AddableDatabaseDatasourceClassBase(DomainClass initialObject, ISessionWrapper dbSession)
{
m_DbObject = initialObject;
//Do stuff like calling SetSession(dbSession);
}
//Several functions and stuff like SetSession(ISessionWrapper dbSession)
}
I also got a lot (>20) of datasource-classes for the use in wpf-datagrids.
class CurrencyDatasource : AddableDatabaseDatasourceClassBase<Currency>
{
//The constructors look always the same
public CurrencyDatasource()
:base()
{
}
public CurrencyDatasource(Currency initialExchange, ISessionWrapper dbSession)
:base(initialExchange, dbSession)
{
}
//Following Properties are always different
public string Name
{
get
{
return m_DbObject.Name;
}
set
{
m_DbObject.Name = value;
}
}
}
So I wonder if there is a way to avoid having to write the same code (the 2 constructors + their call to the base class) in every Datasource class?
or
If this is not possible:
At least define that all classes which are derived from DatabaseDatasourceClassBase have to have these 2 Constructors?
So I wonder if there is a way to avoid having to write the same code (the 2 constructors + their call to the base class) in every Datasource class?
Each class must provide their own constructor(s) and define how they wish to call the base class's constructor(s).
At least define that all classes which are derived from DatabaseDatasourceClassBase have to have these 2 Constructors?
Classes must call at least one base class constructor, but there is no way to enforce which one, or require more than one base constructor be hooked up.
That's at least in code.
I guess you could do something crazy with static code analysis.

Derived constructor with type parameter

EDIT: added follow up question from getting a solution suggested from another question
EDIT2: I just realised that my follow up question was not needed.
Is it possible to have an abstract base class with a type parameter of T have a constructor that takes a parameter of T and assigns it to a property of T? What i want to achieve is that all derived classes has a constructor that does this?
Something like:
public abstract class NotificationBase <T>
{
public string Text { get; set; }
public T Context { get; set; }
public NotificationBase(T context, string text)
{
Context = context;
Text = text;
}
}
public class NumberNotification : NotificationBase<int>{}
public class Program
{
public void Run()
{
var thing = new NumberNotification(10, "Hello!");
}
}
EDIT:
I got a link to another question that explained how to do this which is great. However i have some issues with that. And i dont mean its wrong, if that is the only way to do it then thats how it is. However its not the ideal situation for what im trying to do. I explain. This was the solution:
public class Base
{
public Base(Parameter p)
{
Init(p)
}
void Init(Parameter p)
{
// common initialisation code
}
}
public class Derived : Base
{
public Derived(Parameter p) : base(p)
{
}
}
..which works great. However it does create two small issues that id like to se if they can be addressed.
What i want is to force all classes that derives from the base to pass a T into the constructor so that its mandatory. With this solution, its possible to leave it out.
If all classes should do this then it feels redundant to create a constructor to propagate a mandatory parameter.
EDIT: I just realised that demanding a constructor that propagates the type parameter IS what im looking for. I makes sure that the T property gets a value and also allows for other things to happen in the constructor.
Yes, you can, you just need to propagate the constructor chain using the relevant type, and call the ancestor if needed:
public class NumberNotification : NotificationBase<int>
{
public NumberNotification(int context, string text)
: base(context, text)
{
}
}
Without constructor in child class, the instantiation you wrote can't compile because you don't offer a way for the compiler to know what to do.
You can also offer any other constructor needed.
Therefore now this compiles and works:
var thing = new NumberNotification(10, "Hello!");
Inheritance And Constructors (C# Corner)
base (C# Reference)
Define the parameterized constructor for NumberNotification class which should invoke the required constructor of NotificationBase using base
public class NumberNotification : NotificationBase<int>
{
public NumberNotification(int context, string text)
:base(context, text)
{
}
}
Now for NumberNotification object, context is type of int as here T is marked as int type which Yyou can check using below code:
var thing = new NumberNotification(10, "Hello!");
Console.WriteLine(thing.Context.GetType());
The above prints the output as System.Int32
Check the fiddle - https://dotnetfiddle.net/keufQO

Using parameter in constructors C#

I'm abit new in C#. I have some code like this:
namespace Example
{
public partial class Example_Setting : Form
{
public Example_Setting(String somethings)
{
}
private myPlace()
{
MessageBox.Show(somethings);
}
}
I don't know how to get value of somethings variable in myPlace().How can I do?
An example would be:
namespace Example
{
public partial class Example_Setting : Form
{
string somethings; // <-- declare a variable in the class
public Example_Setting(String somethings)
{
this.somethings = somethings; // save param to variable
}
private myPlace()
{
MessageBox.Show(somethings); // now data is here for use
}
}
I think you can use below code.Declaring the other variable and assign it into constructore and then you can use it in whole class.
public partial class Example_Setting : Form
{
public string some;
public Example_Setting(String somethings)
{
this.some = something;
}
private myPlace()
{
MessageBox.Show(this.some);
}
}
Others have already demonstrated an example. I just want to point out why you can't access somethings from myPlace.
In the example provided in your question, somethings is scoped locally to the constructor. That is, once the constructor has completed, somethings is no longer available to reference and use. In the examples others have provided, they scope somethings to the class, and then assign a the value provided in the constructor parameter. Since somethings is scoped to the class, your other methods (and properties) can access it. Note that if you use public, others outside of the class can use it as well. Best practice though is to keep it private and if you need public access, to use a property.

IntelliSense doesn't show partial class method

I have partial class User generated by LINQtoSQL as shortly following:
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")]
public partial class User : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
...
Then I created separate folder "Proxy" in my project and put there extra piece of User class:
namespace LINQtoSQL_sample.Proxy
{
public partial class User
{
public static string GetActivationUrl()
{
return Guid.NewGuid().ToString("N");
...
Issue happens when I try to invoke that extra static method from another part of same project. Let's say I have once more folder "SqlRepositoryImpl" and another one partial class there:
namespace LINQtoSQL_sample.SqlRepositoryImpl
{
public partial class SqlRepository
{
public bool CreateUser(User instance)
{
if (instance.ID == 0)
{
instance.added_date = DateTime.Now;
instance.activated_link = LINQtoSQL_sample.Proxy.User.GetActivationUrl();
...
As you can see I explicitly defined which part of User class I'm calling for because IntelliSense didn't suggest me my extra method.
Please, advise why such happens and where I'm wrong?
As you can see I explicitly defined which part of User class I'm calling for because IntelliSense didn't suggest me my extra method.
When you call a method from a class, there are no “parts” of the class anymore.
If you need to (and can) specify the full namespace of the class to invoke a method from it that means you actually have two different classes in two different namespaces. If the two partial declarations are in different namespaces, then you have actually declared two separate classes, not a single class from two parts.

Override Default Constructor of Partial Class with Another Partial Class

I don't think this is possible, but if is then I need it :)
I have a auto-generated proxy file from the wsdl.exe command line tool by Visual Studio 2008.
The proxy output is partial classes. I want to override the default constructor that is generated. I would rather not modify the code since it is auto-generated.
I tried making another partial class and redefining the default constructor, but that doesn't work. I then tried using the override and new keywords, but that doesn't work.
I know I could inherit from the partial class, but that would mean I'd have to change all of our source code to point to the new parent class. I would rather not have to do this.
Any ideas, work arounds, or hacks?
//Auto-generated class
namespace MyNamespace {
public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public MyWebService() {
string myString = "auto-generated constructor";
//other code...
}
}
}
//Manually created class in order to override the default constructor
namespace MyNamespace {
public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public override MyWebService() { //this doesn't work
string myString = "overridden constructor";
//other code...
}
}
}
I had a similar problem, with my generated code being created by a DBML file (I'm using Linq-to-SQL classes).
In the generated class it calls a partial void called OnCreated() at the end of the constructor.
Long story short, if you want to keep the important constructor stuff the generated class does for you (which you probably should do), then in your partial class create the following:
partial void OnCreated()
{
// Do the extra stuff here;
}
This is not possible.
Partial classes are essentially parts of the same class; no method can be defined twice or overridden, and that includes the constructor.
You could call a method in the constructor, and only implement it in the other part file.
Hmmm,
I think one elegant solution would be the following:
//* AutogenCls.cs file
//* Let say the file is auto-generated ==> it will be overridden each time when
//* auto-generation will be triggered.
//*
//* Auto-generated class, let say via xsd.exe
//*
partial class AutogenCls
{
public AutogenCls(...)
{
}
}
//* AutogenCls_Cunstomization.cs file
//* The file keeps customization code completely separated from
//* auto-generated AutogenCls.cs file.
//*
partial class AutogenCls
{
//* The following line ensures execution at the construction time
MyCustomization m_MyCustomizationInstance = new MyCustomization ();
//* The following inner&private implementation class implements customization.
class MyCustomization
{
MyCustomization ()
{
//* IMPLEMENT HERE WHATEVER YOU WANT TO EXECUTE DURING CONSTRUCTION TIME
}
}
}
This approach has some drawbacks (as everything):
It is not clear when exactly will be executed the constructor of the MyCustomization inner class during whole construction procedure of the AutogenCls class.
If there will be necessary to implement IDiposable interface for the MyCustomization class to correctly handle disposing of unmanaged resources of the MyCustomization class, I don't know (yet) how to trigger the MyCustomization.Dispose() method without touching the AutogenCls.cs file ... (but as I told 'yet' :)
But this approach offers great separation from auto-generated code - whole customization is separated in different src code file.
enjoy :)
Actually, this is now possible, now that partial methods have been added. Here's the doc:
http://msdn.microsoft.com/en-us/library/wa80x488.aspx
Basically, the idea is that you can declare and call a method in one file where you are defining the partial class, but not actually define the method in that file. In the other file, you can then define the method. If you are building an assembly where the method is not defined, then the ORM will remove all calls to the function.
So in the case above it would look like this:
//Auto-generated class
namespace MyNamespace {
public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol {
public MyWebService() {
string myString = "auto-generated constructor";
OtherCode();
}
}
}
partial void OtherCode();
//Manually created class in order to override the default constructor
partial void OtherCode()
{
//do whatever extra stuff you wanted.
}
It is somewhat limited, and in this particular case, where you have a generated file that you'd need to alter, it might not be the right solution, but for others who stumbled on this trying to override functionality in partial classes, this can be quite helpful.
The problem that the OP has got is that the web reference proxy doesn't generate any partial methods that you can use to intercept the constructor.
I ran into the same problem, and I can't just upgrade to WCF because the web service that I'm targetting doesn't support it.
I didn't want to manually amend the autogenerated code because it'll get flattened if anyone ever invokes the code generation.
I tackled the problem from a different angle. I knew my initialization needed doing before a request, it didn't really need to be done at construction time, so I just overrode the GetWebRequest method like so.
protected override WebRequest GetWebRequest(Uri uri)
{
//only perform the initialization once
if (!hasBeenInitialized)
{
Initialize();
}
return base.GetWebRequest(uri);
}
bool hasBeenInitialized = false;
private void Initialize()
{
//do your initialization here...
hasBeenInitialized = true;
}
This is a nice solution because it doesn't involve hacking the auto generated code, and it fits the OP's exact use case of performing initialization login for a SoapHttpClientProtocol auto generated proxy.
You can't do this. I suggest using a partial method which you can then create a definition for. Something like:
public partial class MyClass{
public MyClass(){
... normal construction goes here ...
AfterCreated();
}
public partial void OnCreated();
}
The rest should be pretty self explanatory.
EDIT:
I would also like to point out that you should be defining an interface for this service, which you can then program to, so you don't have to have references to the actual implementation. If you did this then you'd have a few other options.
I am thinking you might be able to do this with PostSharp, and it looks like someone has done just what you want for methods in generated partial classes. I don't know if this will readily translate to the ability to write a method and have its body replace the constructor as I haven't given it a shot yet but it seems worth a shot.
Edit: this is along the same lines and also looks interesting.
Sometimes you don't have access or it's not allowed to change the default constructor, for this reason you cannot have the default constructor to call any methods.
In this case you can create another constructor with a dummy parameter, and make this new constructor to call the default constructor using ": this()"
public SomeClass(int x) : this()
{
//Your extra initialization here
}
And when you create a new instance of this class you just pass dummy parameter like this:
SomeClass objSomeClass = new SomeClass(0);
This is in my opinion a design flaw in the language. They should have allowed multiple implementations of one partial method, that would have provided a nice solution.
In an even nicer way the constructor (also a method) can then also be simply be marked partial and multiple constructors with the same signature would run when creating an object.
The most simple solution is probably to add one partial 'constructor' method per extra partial class:
public partial class MyClass{
public MyClass(){
... normal construction goes here ...
OnCreated1();
OnCreated2();
...
}
public partial void OnCreated1();
public partial void OnCreated2();
}
If you want the partial classes to be agnostic about each other, you can use reflection:
// In MyClassMyAspect1.cs
public partial class MyClass{
public void MyClass_MyAspect2(){
... normal construction goes here ...
}
}
// In MyClassMyAspect2.cs
public partial class MyClass{
public void MyClass_MyAspect1(){
... normal construction goes here ...
}
}
// In MyClassConstructor.cs
public partial class MyClass : IDisposable {
public MyClass(){
GetType().GetMethods().Where(x => x.Name.StartsWith("MyClass"))
.ForEach(x => x.Invoke(null));
}
public void Dispose() {
GetType().GetMethods().Where(x => x.Name.StartsWith("DisposeMyClass"))
.ForEach(x => x.Invoke(null));
}
}
But really they should just add some more language constructs to work with partial classes.
For a Web service proxy generated by Visual Studio, you cannot add your own constructor in the partial class (well you can, but it does not get called). Instead, you can use the [OnDeserialized] attribute (or [OnDeserializing]) to hook in your own code at the point where the web proxy class is instantiated.
using System.Runtime.Serialization;
partial class MyWebService
{
[OnDeserialized]
public void OnDeserialized(StreamingContext context)
{
// your code here
}
}
I'm not quite addressing the OP, but if you happen to be generating classes with the EntityFramework Reverse POCO Generator, there's a partial method called in the constructor which is handy for initializing things you're adding via partial classes on your own...
Generated by tool:
[System.CodeDom.Compiler.GeneratedCode("EF.Reverse.POCO.Generator", "2.37.3.0")]
public partial class Library {
public string City { get; set; }
public Library() {
InitializePartial();
}
partial void InitializePartial();
}
added by you:
public partial class Library {
List<Book> Books { get; set; }
partial void InitializePartial() {
Books = new List<Book>();
}
}
public class Book {
public string Title { get; set; }
}
A bit late to the game, but this is indeed possible. Kind of.
I recently performed the trick below in a code generator of mine, and the result is satisfying. Yes, a dummy argument is required, but it will not cause any major concerns. For consistency, you may want to apply some rules:
Rules
Manually created constructor must be protected.
Generated constructor must be public, with the same arguments as the protected one plus an extra optional dummy argument.
The generated constructor calls the original constructor with all the supplied arguments.
This works for regular construction as well as reflection:
var s1 = new MyWebService();
var s2 = (MyWebService?)Activator.CreateInstance(
typeof(MyWebService),
BindingFlags.CreateInstance | BindingFlags.Public);
And for IoC, it should also work (verified in DryIoc). The container resolves the injected arguments, skipping the optional ones:
var service = container.Resolve<MyWebService>();
Sample code
// <auto-generated />
public partial class MyWebService
{
public MyWebService(object? dummyArgument = default)
: this()
{
// Auto-generated constructor
}
}
// Manually created
public partial class MyWebService
{
protected MyWebService()
{
}
}
The above works for any number of constructor arguments. As for the dummy arguments, we could invent a special type (maybe an enum) further restricting possible abuse of this extra argument.
Nothing that I can think of. The "best" way I can come up with is to add a ctor with a dummy parameter and use that:
public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol
{
public override MyWebService(int dummy)
{
string myString = "overridden constructor";
//other code...
}
}
MyWebService mws = new MyWebService(0);

Categories

Resources