0

I have the following function :

public override void LoadDataToControls<T>(T Id)
{

}

I want to assign the Id parameter to a Guid variable inside the function , how can I acheive this ?

and here is the abstract base class code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BMS.Classes.Helpers
{
    public abstract class BasicPageFunctionsHelper : System.Web.UI.Page
    {
        public abstract void BindGrid();
        public abstract void ClearControls();
        public abstract void LoadDataToControls<T>(T ID);
        public abstract void EnableDisableControls(bool Enable);
        public abstract void SetPageStatus(EnumHelper.PageStatus PageStatus);
        public abstract bool ValidateInsert();
        public abstract bool ValidateUpdate();
        public abstract bool ValidateDelete();
    }
}
gwt
  • 2,331
  • 4
  • 37
  • 59
  • 2
    Why not just declare the parameter as a `Guid`? – Steve Czetty Oct 01 '13 at 18:06
  • @Steve Czetty I am inheriting an abstract class and though overriding some methods in my pages , and the Id Type might be different in different pages , that's whay ;) – gwt Oct 01 '13 at 18:08
  • @Karamafrooz Then have two different methods; one for guids, and one for other stuff, since you need to handle them differently. – Servy Oct 01 '13 at 18:10
  • @Servy what's the benefit of having two or more methods while one method with a generic parameter can handle them all ? – gwt Oct 01 '13 at 18:12
  • 4
    @Karamafrooz Because the method isn't logically generic. It's two different methods stuffed into one. The single responsibility principle is violated. If you need to handle two different types differently then have two methods to handle the two types. If you can do the same thing on different types because you don't *care* what type it is, then it's a case where generics may be appropriate. – Servy Oct 01 '13 at 18:13
  • @Servy In each page I only use the method once , I mean in each page the responsibility is single , I really don't get why It matters if the parameter type is different in another page ? – gwt Oct 01 '13 at 18:18
  • @Karamafrooz The parameters being different isn't a problem; that's fine, the problem is that you're treating each type differently. If you instead have multiple overloads of the method overload resolution will ensure that the proper implementation is called for the proper object. – Servy Oct 01 '13 at 18:19
  • 1
    @Karamafrooz what Servy is saying is that a generic method _should be type ignorant_ - that is, the class/method works the same for all types. Your method, on the other hand, is casting the generic parameter to a concrete type. You're handling a type with as a special case and it is therefore **not generic at all**. – Dave Zych Oct 01 '13 at 18:23
  • What does the class declaration look like? Is this class and the abstract base class both non-generic? Maybe the base class should be generic, and its abstract method be non-generic and use the type parameter of the base class. Then you could have `public class ThisClass : TheBaseClass`. But hard to tell from what we know. – Jeppe Stig Nielsen Oct 01 '13 at 18:29
  • @JeppeStigNielsen I added the Abstract Base class Code – gwt Oct 01 '13 at 18:32
  • Would it be possible to have `public abstract class BasicPageFunctionsHelper : System.Web.UI.Page` (generic) and inside it `public abstract void LoadDataToControls(T_ID id);` (non-generic)? Then the concrete class should be `public class SomePage : BasicPageFunctionsHelper`. – Jeppe Stig Nielsen Oct 01 '13 at 18:46

3 Answers3

3

I want to assign the Id parameter to a Guid variable inside the function , how can I acheive this ?

If I understand it correctly then:

Guid guid = Guid.Parse(Id.ToString());

Or use Guid.TryParse, if the type passed is not a GUID, it will not give an exception. like:

Guid guid;
if (Guid.TryParse(Id.ToString(), out guid))
{
    //successfull parsing
}
else
{
    //not a guid
}

Although, if your method is dealing with a particular type, then it doesn't really useful to have it as a generic in first place.

EDIT: If you are passing an object of GUID type then you can compare its type with is like:

Guid guid;
if (Id is Guid)
{
    guid = (Guid)(object)Id;
}

(This has already been mentioned in @Sriram Sakthivel answer)

Community
  • 1
  • 1
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 1
    it'll compile, but if the types *aren't* guids then it'll just break at runtime. It's not really any different than a cast, except that it's slower. As for checking, if you're checking what a type is then the method isn't logically generic, and shouldn't be using that language feature. – Servy Oct 01 '13 at 18:10
  • @Servy, just added `Guid.TryParse` if the passed element is not a GUID – Habib Oct 01 '13 at 18:11
  • @Habib That's still likely not the proper approach to a problem such as this, as per my edit. – Servy Oct 01 '13 at 18:12
  • @Servy, I am not sure about his situation, but according to OP he is inheriting from a base class, and can't really change that. – Habib Oct 01 '13 at 18:13
  • It's [better](http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr) to do `Guid? g = Id as Guid?' if (g != null) ...` – abatishchev Oct 02 '13 at 06:35
0

Just to be complete, this might be the better way to do it. Define an interface that has the functionality you want and then require that interface in the generic definition. This will force the programer and compiler to ensure 100% type-safe run-time code.

public interface IASGUID
{
   Guid GetGuid();
}


public override void LoadDataToControls<T>(T Id) Where T : IASGUID
{

  // then auto type-checked -- no run-time error possible.

  Guid guid = Id.GetGuid(); 

}
Hogan
  • 69,564
  • 10
  • 76
  • 117
  • In such a case there isn't even a need to use generics; just have the parameter be typed as the interface. – Servy Oct 01 '13 at 18:18
  • @Servy - who is to say why the OQ is like this? It could be a legacy code thing. This does solve the problem and can be made more elegant (but that gets complicated quick). Like requiring a helper function that performs the conversion. Then it can all be written outside of legacy code. – Hogan Oct 01 '13 at 18:20
  • This whole thing smells, yes, but we don't know what else is in LoadDataToControls that might need it to be generic. – Mark Sowul Oct 01 '13 at 18:21
-1

If I understand correctly then you need to assign Id to a Guid

Try this. Note this involves boxing/unboxing may not be a optimal way. But if you're not concerned about performance this should help.

public override void LoadDataToControls<T>(T Id)
{
    if(id is Guid)
    {
        Guid guid = (Guid)(object)id;
    }
}
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • This evades all type-safety and does not work if Id is not a Guid – Mark Sowul Oct 01 '13 at 18:22
  • @MarkSowul Just like the accepted answer, except this answer does it much more efficiently and with shorter, simpler, and clearer code. – Servy Oct 01 '13 at 18:23
  • 1
    @Servy, the accepted answer has `Guid.TryParse` option as well. – Habib Oct 01 '13 at 18:24
  • @Habib And this answer checks the type as well, again, doing so in a way that's much more efficient, simpler, semantically correct, and clearer, than your code. The're *both* still entirely inappropriate appropriate in that they are abusing generics, but they're equally bad in that regard. – Servy Oct 01 '13 at 18:25
  • @MarkSowul I think this is type safe since I use `is` keyword no chance to mess up. and What I understand is OP passes a `Guid` inside but can't able to convert it to `Guid` so no need to make it work if parameter is not Guid – Sriram Sakthivel Oct 01 '13 at 18:26
  • Any downvoter If you can provide a good answer pls provide that, them downvote. Not to downvote if you have enough reputation to downvote. This perfectly answers the question as well. – Sriram Sakthivel Oct 01 '13 at 18:30
  • This is a valid answer, Even if I get 100 downvotes am not going to remove this answer. And I don't see any better answer than this too(upto my knowledge)! – Sriram Sakthivel Oct 01 '13 at 18:31
  • @Habib `Guid.TryParse` is a dirty idea without knowing what is the type of `T` – Sriram Sakthivel Oct 01 '13 at 18:33
  • @SriramSakthivel, yes it is, but [checking type in a generic method is dirty](http://stackoverflow.com/questions/2004508/checking-type-parameter-of-a-generic-method-in-c-sharp) as well. – Habib Oct 01 '13 at 18:35
  • @Habib Yours is almost certainly worse, because that's essentially what you are doing, you're just doing it in a less efficient, more roundabout way. This answer is still quite bad, but it's bad in a way that's a lot better than your answer. – Servy Oct 01 '13 at 18:36
  • @Servy, I can only **assume** that the OP is passing string guid, and hence it worked for him. Again I **didn't downvote** this answer – Habib Oct 01 '13 at 18:42
  • @Habib Consider `T` is a `Form` still you're converting `form.ToString()` and trying to parse it as `Guid`. Is that good one? And even if this solution is dirty I feel this is the straight way to do that inside a generic method. – Sriram Sakthivel Oct 01 '13 at 18:43
  • @Habib The OP gave no indication that he's passing a string as a Guid. He says he's passing a Guid. Your code works for a Guid. It's terribly inefficient as it's converting a Guid to a string just to parse it, and, as per previous discussions, the overall design is awful, but it doesn't require the input to be a string. – Servy Oct 01 '13 at 18:44
  • @SriramSakthivel, would your function work if you pass it a value like: `obj.LoadDataToControls("e5560be3-f333-4ced-a07f-c8694381fabd")` – Habib Oct 01 '13 at 18:44
  • 1
    @Habib Is that a requirement to make function work when we pass a string? Why do you answer a question which is not being asked? – Sriram Sakthivel Oct 01 '13 at 18:46
  • @Servy, I see the point. You are right. If the parameter passed is GUID this answer is much much better, My only assumption to begin with was that the parameter passed is string. I know its not mentioned anywhere in the question, but I just went with this assumption. – Habib Oct 01 '13 at 18:48
  • @Habib And one more thing, If this is dirty solution then why JonSkeet has to give it as an answer? I think there is no other way you can do it. Why no downvotes for jon? Because that is the question being asked. here also case is same – Sriram Sakthivel Oct 01 '13 at 18:49